Mercurial > mplayer.hg
annotate gui/interface.c @ 23572:a00685941686
demux_mkv very long seek fix
The seek code searching for the closest position in the index used
"int64_t min_diff=0xFFFFFFFL" as the initial "further from the goal
than any real alternative" value. The unit is milliseconds so seeks more
than about 75 hours past the end of the file would fail to recognize the
last index position as the best match. This was triggered in practice by
chapter seek code which apparently uses a seek of 1000000000 seconds
forward to mean "seek to the end". The practical effect was that trying
to seek to the next chapter in a file without chapters made MPlayer
block until it finished reading the file from the current position to
the end.
Fixed by increasing the initial value from FFFFFFF to FFFFFFFFFFFFFFF.
author | uau |
---|---|
date | Wed, 20 Jun 2007 18:19:03 +0000 |
parents | 74f5109611e2 |
children | c1221a031ab7 |
rev | line source |
---|---|
23077 | 1 |
2 #include <inttypes.h> | |
3 #include <stdlib.h> | |
4 #include <stdio.h> | |
5 #include <string.h> | |
6 #include <sys/types.h> | |
7 | |
8 #include "wm/ws.h" | |
9 #include "wm/wsxdnd.h" | |
10 #include "interface.h" | |
11 #include "skin/skin.h" | |
12 | |
13 #include "mplayer/gtk/eq.h" | |
14 #include "mplayer/widgets.h" | |
15 #include "mplayer/gmplayer.h" | |
16 #include "mplayer/play.h" | |
17 | |
18 #include "mplayer.h" | |
19 #include "access_mpcontext.h" | |
20 #include "app.h" | |
21 #include "cfg.h" | |
22 #include "help_mp.h" | |
23 #include "subreader.h" | |
24 #include "libvo/x11_common.h" | |
25 #include "libvo/video_out.h" | |
26 #include "libvo/font_load.h" | |
27 #include "libvo/sub.h" | |
28 #include "input/input.h" | |
29 #include "libao2/audio_out.h" | |
30 #include "mixer.h" | |
31 #include "libaf/af.h" | |
32 #include "libaf/equalizer.h" | |
33 | |
34 extern af_cfg_t af_cfg; | |
35 | |
36 #ifdef USE_ICONV | |
37 #include <iconv.h> | |
38 #endif | |
39 | |
40 #include "stream/stream.h" | |
41 #include "libmpdemux/demuxer.h" | |
42 #include "libmpdemux/stheader.h" | |
43 #include "libmpcodecs/dec_video.h" | |
44 | |
45 #ifdef USE_DVDREAD | |
46 #include "stream/stream_dvd.h" | |
47 #endif | |
48 | |
49 | |
50 #include "m_config.h" | |
51 #include "m_option.h" | |
52 | |
53 | |
54 guiInterface_t guiIntfStruct; | |
55 int guiWinID=-1; | |
56 | |
57 char * gstrcat( char ** dest,const char * src ) | |
58 { | |
59 char * tmp = NULL; | |
60 | |
61 if ( !src ) return NULL; | |
62 | |
63 if ( *dest ) | |
64 { | |
65 tmp=malloc( strlen( *dest ) + strlen( src ) + 1 ); | |
66 | |
67 if ( tmp ) /* TODO: advanced error handling */ | |
68 { | |
69 strcpy( tmp,*dest ); strcat( tmp,src ); free( *dest ); | |
70 } | |
71 } | |
72 else | |
73 { tmp=malloc( strlen( src ) + 1 ); strcpy( tmp,src ); } | |
74 *dest=tmp; | |
75 return tmp; | |
76 } | |
77 | |
78 int gstrcmp( const char * a,const char * b ) | |
79 { | |
80 if ( !a && !b ) return 0; | |
81 if ( !a || !b ) return -1; | |
82 return strcmp( a,b ); | |
83 } | |
84 | |
85 int gstrncmp( const char * a,const char * b,int size ) | |
86 { | |
87 if ( !a && !b ) return 0; | |
88 if ( !a || !b ) return -1; | |
89 return strncmp( a,b,size ); | |
90 } | |
91 | |
92 char * gstrdup( const char * str ) | |
93 { | |
94 if ( !str ) return NULL; | |
95 return strdup( str ); | |
96 } | |
97 | |
98 char * gstrchr( char * str,int c ) | |
99 { | |
100 if ( !str ) return NULL; | |
101 return strchr( str,c ); | |
102 } | |
103 | |
104 void gfree( void ** p ) | |
105 { | |
106 if ( *p == NULL ) return; | |
107 free( *p ); *p=NULL; | |
108 } | |
109 | |
110 void gset( char ** str, const char * what ) | |
111 { | |
112 if ( *str ) { if ( !strstr( *str,what ) ) { gstrcat( str,"," ); gstrcat( str,what ); }} | |
113 else gstrcat( str,what ); | |
114 } | |
115 | |
116 /** | |
117 * \brief this actually creates a new list containing only one element... | |
118 */ | |
119 void gaddlist( char *** list,const char * entry ) | |
120 { | |
121 int i; | |
122 | |
123 if ( (*list) ) | |
124 { | |
125 for ( i=0;(*list)[i];i++ ) free( (*list)[i] ); | |
126 free( (*list) ); | |
127 } | |
128 | |
129 (*list)=malloc( 2 * sizeof(char **) ); | |
130 (*list)[0]=gstrdup( entry ); | |
131 (*list)[1]=NULL; | |
132 } | |
133 | |
134 /** | |
135 * \brief this replaces a string starting with search by replace. | |
136 * If not found, replace is appended. | |
137 */ | |
138 void greplace(char ***list, const char *search, const char *replace) | |
139 { | |
140 int i = 0; | |
141 int len = (search) ? strlen(search) : 0; | |
142 | |
143 if (*list) { | |
144 for (i = 0; (*list)[i]; i++) { | |
145 if (search && (strncmp((*list)[i], search, len) == 0)) { | |
146 free((*list)[i]); | |
147 (*list)[i] = gstrdup(replace); | |
148 return; | |
149 } | |
150 } | |
151 *list = realloc(*list, (i + 2) * sizeof(char *)); | |
152 } | |
153 else | |
154 *list = malloc(2 * sizeof(char *)); | |
155 | |
156 (*list)[i] = gstrdup(replace); | |
157 (*list)[i + 1] = NULL; | |
158 } | |
159 | |
160 #ifdef USE_ICONV | |
161 char * gconvert_uri_to_filename( char * str ) | |
162 { | |
163 iconv_t d; | |
164 char * out = strdup( str ); | |
165 char * tmp = NULL; | |
166 char * ize; | |
167 size_t inb,outb; | |
168 char * charset = "ISO8859-1"; | |
169 char * cs; | |
170 | |
171 if ( !strchr( str,'%' ) ) return str; | |
172 | |
173 { | |
174 char * t = calloc( 1,strlen( out ) ); | |
175 int i,c = 0; | |
176 for ( i=0;i < (int)strlen( out );i++ ) | |
177 if ( out[i] != '%' ) t[c++]=out[i]; | |
178 else | |
179 { | |
180 char tmp[5] = "0xXX"; | |
181 // if ( out[++i] == '%' ) { t[c++]='%'; continue; }; | |
182 tmp[2]=out[++i]; tmp[3]=out[++i]; | |
183 t[c++]=(char)strtol( tmp,(char **)NULL,0 ); | |
184 } | |
185 free( out ); | |
186 out=t; | |
187 } | |
188 | |
189 if ( (cs=getenv( "CHARSET" )) && *cs ) charset=cs; | |
190 | |
191 inb=outb=strlen( out ); | |
192 tmp=calloc( 1,outb + 1 ); | |
193 ize=tmp; | |
194 d=iconv_open( charset,"UTF-8" ); | |
195 if ( (iconv_t)(-1) == d ) return str; | |
196 iconv( d,&out,&inb,&tmp,&outb ); | |
197 iconv_close( d ); | |
198 free( out ); | |
199 return ize; | |
200 } | |
201 #endif | |
202 | |
203 void guiInit( void ) | |
204 { | |
205 int i; | |
206 | |
207 memset( &guiIntfStruct,0,sizeof( guiIntfStruct ) ); | |
208 guiIntfStruct.Balance=50.0f; | |
209 guiIntfStruct.StreamType=-1; | |
210 | |
211 memset( >kEquChannels,0,sizeof( gtkEquChannels ) ); | |
212 #ifdef HAVE_DXR3 | |
213 if ( !gtkDXR3Device ) gtkDXR3Device=strdup( "/dev/em8300-0" ); | |
214 #endif | |
215 if ( stream_cache_size > 0 ) { gtkCacheOn=1; gtkCacheSize=stream_cache_size; } | |
216 else if ( stream_cache_size == 0 ) gtkCacheOn = 0; | |
217 if ( autosync && autosync != gtkAutoSync ) { gtkAutoSyncOn=1; gtkAutoSync=autosync; } | |
218 | |
219 #ifdef USE_ASS | |
220 gtkASS.enabled = ass_enabled; | |
221 gtkASS.use_margins = ass_use_margins; | |
222 gtkASS.top_margin = ass_top_margin; | |
223 gtkASS.bottom_margin = ass_bottom_margin; | |
224 #endif | |
225 | |
226 gtkInit(); | |
227 // --- initialize X | |
228 wsXInit( (void *)mDisplay ); | |
229 // --- load skin | |
230 skinDirInHome=get_path("skins"); | |
231 skinDirInHome_obsolete=get_path("Skin"); | |
232 skinMPlayerDir=MPLAYER_DATADIR "/skins"; | |
233 skinMPlayerDir_obsolete=MPLAYER_DATADIR "/Skin"; | |
234 mp_msg( MSGT_GPLAYER,MSGL_V,"SKIN dir 1: '%s'\n",skinDirInHome); | |
235 mp_msg( MSGT_GPLAYER,MSGL_V,"SKIN dir 1 (obsolete): '%s'\n",skinDirInHome_obsolete); | |
236 mp_msg( MSGT_GPLAYER,MSGL_V,"SKIN dir 2: '%s'\n",skinMPlayerDir); | |
237 mp_msg( MSGT_GPLAYER,MSGL_V,"SKIN dir 2 (obsolete): '%s'\n",skinMPlayerDir_obsolete); | |
238 if ( !skinName ) skinName=strdup( "default" ); | |
239 i = skinRead( skinName ); | |
240 if ((i == -1) && strcmp(skinName,"default")) | |
241 { | |
242 mp_msg( MSGT_GPLAYER,MSGL_WARN,MSGTR_SKIN_SKINCFG_SelectedSkinNotFound, skinName); | |
243 skinName=strdup( "default" ); | |
244 i = skinRead( skinName ); | |
245 } | |
246 switch (i) { | |
247 case -1: mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_SKIN_SKINCFG_SkinNotFound,skinName ); exit( 0 ); | |
248 case -2: mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_SKIN_SKINCFG_SkinCfgReadError,skinName ); exit( 0 ); | |
249 } | |
250 // --- initialize windows | |
251 if ( ( mplDrawBuffer = malloc( appMPlayer.main.Bitmap.ImageSize ) ) == NULL ) | |
252 { | |
253 fprintf( stderr,MSGTR_NEMDB ); | |
254 exit( 0 ); | |
255 } | |
256 | |
257 if ( gui_save_pos ) | |
258 { | |
259 appMPlayer.main.x = gui_main_pos_x; | |
260 appMPlayer.main.y = gui_main_pos_y; | |
261 appMPlayer.sub.x = gui_sub_pos_x; | |
262 appMPlayer.sub.y = gui_sub_pos_y; | |
263 } | |
264 | |
265 if (WinID>0) | |
266 { | |
267 appMPlayer.subWindow.Parent=WinID; | |
268 appMPlayer.sub.x=0; | |
269 appMPlayer.sub.y=0; | |
270 } | |
271 if (guiWinID>=0) appMPlayer.mainWindow.Parent=guiWinID; | |
272 | |
273 wsCreateWindow( &appMPlayer.subWindow, | |
274 appMPlayer.sub.x,appMPlayer.sub.y,appMPlayer.sub.width,appMPlayer.sub.height, | |
275 wsNoBorder,wsShowMouseCursor|wsHandleMouseButton|wsHandleMouseMove,wsShowFrame|wsHideWindow,"MPlayer - Video" ); | |
276 | |
277 wsDestroyImage( &appMPlayer.subWindow ); | |
278 wsCreateImage( &appMPlayer.subWindow,appMPlayer.sub.Bitmap.Width,appMPlayer.sub.Bitmap.Height ); | |
279 wsXDNDMakeAwareness(&appMPlayer.subWindow); | |
280 | |
281 mplMenuInit(); | |
282 mplPBInit(); | |
283 | |
284 vo_setwindow( appMPlayer.subWindow.WindowID, appMPlayer.subWindow.wGC ); | |
285 | |
286 // i=wsHideFrame|wsMaxSize|wsHideWindow; | |
287 // if ( appMPlayer.mainDecoration ) i=wsShowFrame|wsMaxSize|wsHideWindow; | |
288 i=wsShowFrame|wsMaxSize|wsHideWindow; | |
289 wsCreateWindow( &appMPlayer.mainWindow, | |
290 appMPlayer.main.x,appMPlayer.main.y,appMPlayer.main.width,appMPlayer.main.height, | |
291 wsNoBorder,wsShowMouseCursor|wsHandleMouseButton|wsHandleMouseMove,i,"MPlayer" ); | |
292 | |
293 wsSetShape( &appMPlayer.mainWindow,appMPlayer.main.Mask.Image ); | |
294 wsXDNDMakeAwareness(&appMPlayer.mainWindow); | |
295 | |
296 #ifdef DEBUG | |
297 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[main] depth on screen: %d\n",wsDepthOnScreen ); | |
298 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[main] parent: 0x%x\n",(int)appMPlayer.mainWindow.WindowID ); | |
299 mp_msg( MSGT_GPLAYER,MSGL_DBG2,"[main] sub: 0x%x\n",(int)appMPlayer.subWindow.WindowID ); | |
300 #endif | |
301 | |
302 appMPlayer.mainWindow.ReDraw=(void *)mplMainDraw; | |
303 appMPlayer.mainWindow.MouseHandler=mplMainMouseHandle; | |
304 appMPlayer.mainWindow.KeyHandler=mplMainKeyHandle; | |
305 appMPlayer.mainWindow.DandDHandler=mplDandDHandler; | |
306 | |
307 appMPlayer.subWindow.ReDraw=(void *)mplSubDraw; | |
308 appMPlayer.subWindow.MouseHandler=mplSubMouseHandle; | |
309 appMPlayer.subWindow.KeyHandler=mplMainKeyHandle; | |
310 appMPlayer.subWindow.DandDHandler=mplDandDHandler; | |
311 | |
312 wsSetBackgroundRGB( &appMPlayer.subWindow,appMPlayer.sub.R,appMPlayer.sub.G,appMPlayer.sub.B ); | |
313 wsClearWindow( appMPlayer.subWindow ); | |
314 if ( appMPlayer.sub.Bitmap.Image ) wsConvert( &appMPlayer.subWindow,appMPlayer.sub.Bitmap.Image,appMPlayer.sub.Bitmap.ImageSize ); | |
315 | |
316 btnModify( evSetVolume,guiIntfStruct.Volume ); | |
317 btnModify( evSetBalance,guiIntfStruct.Balance ); | |
318 btnModify( evSetMoviePosition,guiIntfStruct.Position ); | |
319 | |
320 wsSetIcon( wsDisplay,appMPlayer.mainWindow.WindowID,guiIcon,guiIconMask ); | |
321 wsSetIcon( wsDisplay,appMPlayer.subWindow.WindowID,guiIcon,guiIconMask ); | |
322 | |
323 guiIntfStruct.Playing=0; | |
324 | |
325 if ( !appMPlayer.mainDecoration ) wsWindowDecoration( &appMPlayer.mainWindow,0 ); | |
326 | |
327 wsVisibleWindow( &appMPlayer.mainWindow,wsShowWindow ); | |
328 #if 0 | |
329 wsVisibleWindow( &appMPlayer.subWindow,wsShowWindow ); | |
330 | |
331 { | |
332 XEvent xev; | |
333 do { XNextEvent( wsDisplay,&xev ); } while ( xev.type != MapNotify || xev.xmap.event != appMPlayer.subWindow.WindowID ); | |
334 appMPlayer.subWindow.Mapped=wsMapped; | |
335 } | |
336 | |
337 if ( !fullscreen ) fullscreen=gtkLoadFullscreen; | |
338 if ( fullscreen ) | |
339 { | |
340 mplFullScreen(); | |
341 btnModify( evFullScreen,btnPressed ); | |
342 } | |
343 #else | |
344 if ( !fullscreen ) fullscreen=gtkLoadFullscreen; | |
345 if ( gtkShowVideoWindow ) | |
346 { | |
347 wsVisibleWindow( &appMPlayer.subWindow,wsShowWindow ); | |
348 { | |
349 XEvent xev; | |
350 do { XNextEvent( wsDisplay,&xev ); } while ( xev.type != MapNotify || xev.xmap.event != appMPlayer.subWindow.WindowID ); | |
351 appMPlayer.subWindow.Mapped=wsMapped; | |
352 } | |
353 | |
354 if ( fullscreen ) | |
355 { | |
356 mplFullScreen(); | |
357 btnModify( evFullScreen,btnPressed ); | |
358 } | |
359 } | |
360 else | |
361 { | |
362 if ( fullscreen ) | |
363 { | |
364 wsVisibleWindow( &appMPlayer.subWindow,wsShowWindow ); | |
365 { | |
366 XEvent xev; | |
367 do { XNextEvent( wsDisplay,&xev ); } while ( xev.type != MapNotify || xev.xmap.event != appMPlayer.subWindow.WindowID ); | |
368 appMPlayer.subWindow.Mapped=wsMapped; | |
369 } | |
370 wsVisibleWindow( &appMPlayer.subWindow, wsShowWindow ); | |
371 | |
372 mplFullScreen(); | |
373 btnModify( evFullScreen,btnPressed ); | |
374 } | |
375 } | |
376 #endif | |
377 mplSubRender=1; | |
378 // --- | |
379 | |
380 if ( filename ) mplSetFileName( NULL,filename,STREAMTYPE_FILE ); | |
381 if ( plCurrent && !filename ) mplSetFileName( plCurrent->path,plCurrent->name,STREAMTYPE_FILE ); | |
382 if ( subdata ) guiSetFilename( guiIntfStruct.Subtitlename, subdata->filename ); | |
383 guiLoadFont(); | |
384 } | |
385 | |
386 void guiDone( void ) | |
387 { | |
388 mplMainRender=0; | |
389 mp_msg( MSGT_GPLAYER,MSGL_V,"[GUI] done.\n" ); | |
390 | |
391 if ( gui_save_pos ) | |
392 { | |
393 gui_main_pos_x=appMPlayer.mainWindow.X; gui_main_pos_y=appMPlayer.mainWindow.Y; | |
394 gui_sub_pos_x=appMPlayer.subWindow.X; gui_sub_pos_y=appMPlayer.subWindow.Y; | |
395 } | |
396 | |
397 #ifdef USE_ASS | |
398 ass_enabled = gtkASS.enabled; | |
399 ass_use_margins = gtkASS.use_margins; | |
400 ass_top_margin = gtkASS.top_margin; | |
401 ass_bottom_margin = gtkASS.bottom_margin; | |
402 #endif | |
403 | |
404 cfg_write(); | |
405 wsXDone(); | |
406 } | |
407 | |
408 int guiCMDArray[] = | |
409 { | |
410 evLoadPlay, | |
411 evLoadSubtitle, | |
412 evAbout, | |
413 evPlay, | |
414 evStop, | |
415 evPlayList, | |
416 evPreferences, | |
417 evFullScreen, | |
418 evSkinBrowser | |
419 }; | |
420 | |
421 extern int frame_dropping; | |
422 extern int stream_dump_type; | |
423 extern int vcd_track; | |
424 extern m_obj_settings_t * vf_settings; | |
425 | |
426 void guiLoadFont( void ) | |
427 { | |
428 #ifdef HAVE_FREETYPE | |
23341
74f5109611e2
missed part of gui code change while introducing -subfont option (patch by Piotr Kaczuba)
ben
parents:
23158
diff
changeset
|
429 load_font_ft(vo_image_width, vo_image_height, &vo_font, font_name); |
23077 | 430 #else |
431 if ( vo_font ) | |
432 { | |
433 int i; | |
434 if ( vo_font->name ) free( vo_font->name ); | |
435 if ( vo_font->fpath ) free( vo_font->fpath ); | |
436 for ( i=0;i<16;i++ ) | |
437 if ( vo_font->pic_a[i] ) | |
438 { | |
439 if ( vo_font->pic_a[i]->bmp ) free( vo_font->pic_a[i]->bmp ); | |
440 if ( vo_font->pic_a[i]->pal ) free( vo_font->pic_a[i]->pal ); | |
441 } | |
442 for ( i=0;i<16;i++ ) | |
443 if ( vo_font->pic_b[i] ) | |
444 { | |
445 if ( vo_font->pic_b[i]->bmp ) free( vo_font->pic_b[i]->bmp ); | |
446 if ( vo_font->pic_b[i]->pal ) free( vo_font->pic_b[i]->pal ); | |
447 } | |
448 free( vo_font ); vo_font=NULL; | |
449 } | |
450 if ( font_name ) | |
451 { | |
452 vo_font=read_font_desc( font_name,font_factor,0 ); | |
453 if ( !vo_font ) mp_msg( MSGT_CPLAYER,MSGL_ERR,MSGTR_CantLoadFont,font_name ); | |
454 } | |
455 else | |
456 { | |
457 font_name=gstrdup( get_path( "font/font.desc" ) ); | |
458 vo_font=read_font_desc( font_name,font_factor,0 ); | |
459 if ( !vo_font ) | |
460 { | |
461 gfree( (void **)&font_name ); font_name=gstrdup(MPLAYER_DATADIR "/font/font.desc" ); | |
462 vo_font=read_font_desc( font_name,font_factor,0 ); | |
463 } | |
464 } | |
465 #endif | |
466 } | |
467 | |
468 extern mp_osd_obj_t* vo_osd_list; | |
469 | |
470 extern char **sub_name; | |
471 | |
472 void guiLoadSubtitle( char * name ) | |
473 { | |
474 if ( guiIntfStruct.Playing == 0 ) | |
475 { | |
476 guiIntfStruct.SubtitleChanged=1; //what is this for? (mw) | |
477 return; | |
478 } | |
479 if ( subdata ) | |
480 { | |
481 mp_msg( MSGT_GPLAYER,MSGL_INFO,MSGTR_DeletingSubtitles ); | |
482 sub_free( subdata ); | |
483 subdata=NULL; | |
484 vo_sub=NULL; | |
485 if ( vo_osd_list ) | |
486 { | |
487 int len; | |
488 mp_osd_obj_t * osd = vo_osd_list; | |
489 while ( osd ) | |
490 { | |
491 if ( osd->type == OSDTYPE_SUBTITLE ) break; | |
492 osd=osd->next; | |
493 } | |
494 if ( osd && osd->flags&OSDFLAG_VISIBLE ) | |
495 { | |
496 len=osd->stride * ( osd->bbox.y2 - osd->bbox.y1 ); | |
497 memset( osd->bitmap_buffer,0,len ); | |
498 memset( osd->alpha_buffer,0,len ); | |
499 } | |
500 } | |
501 } | |
502 if ( name ) | |
503 { | |
504 mp_msg( MSGT_GPLAYER,MSGL_INFO,MSGTR_LoadingSubtitles,name ); | |
505 subdata=sub_read_file( name, guiIntfStruct.FPS ); | |
506 if ( !subdata ) mp_msg( MSGT_GPLAYER,MSGL_ERR,MSGTR_CantLoadSub,name ); | |
507 sub_name = (malloc(2 * sizeof(char*))); //when mplayer will be restarted | |
508 sub_name[0] = strdup(name); //sub_name[0] will be read | |
509 sub_name[1] = NULL; | |
510 } | |
511 update_set_of_subtitles(); | |
512 | |
513 } | |
514 | |
515 static void add_vf( char * str ) | |
516 { | |
517 mp_msg( MSGT_GPLAYER,MSGL_STATUS,MSGTR_AddingVideoFilter,str ); | |
518 if ( vf_settings ) | |
519 { | |
520 int i = 0; | |
521 while ( vf_settings[i].name ) if ( !gstrcmp( vf_settings[i++].name,str ) ) { i=-1; break; } | |
522 if ( i != -1 ) | |
523 { 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; } | |
524 } 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; } | |
525 } | |
526 | |
527 static void remove_vf( char * str ) | |
528 { | |
529 int n = 0; | |
530 | |
531 if ( !vf_settings ) return; | |
532 | |
533 mp_msg( MSGT_GPLAYER,MSGL_STATUS,MSGTR_RemovingVideoFilter,str ); | |
534 | |
535 while ( vf_settings[n++].name ); n--; | |
536 if ( n > -1 ) | |
537 { | |
538 int i = 0,m = -1; | |
539 while ( vf_settings[i].name ) if ( !gstrcmp( vf_settings[i++].name,str ) ) { m=i - 1; break; } | |
540 i--; | |
541 if ( m > -1 ) | |
542 { | |
543 if ( n == 1 ) { free( vf_settings[0].name );free( vf_settings[0].attribs ); free( vf_settings ); vf_settings=NULL; } | |
544 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 ) ); } | |
545 } | |
546 } | |
547 } | |
548 | |
549 int guiGetEvent( int type,char * arg ) | |
550 { | |
551 ao_functions_t *audio_out = NULL; | |
552 vo_functions_t *video_out = NULL; | |
553 mixer_t *mixer = NULL; | |
554 | |
555 stream_t * stream = (stream_t *) arg; | |
556 #ifdef USE_DVDREAD | |
557 dvd_priv_t * dvdp = (dvd_priv_t *) arg; | |
558 #endif | |
559 | |
560 if (guiIntfStruct.mpcontext) { | |
561 audio_out = mpctx_get_audio_out(guiIntfStruct.mpcontext); | |
562 video_out = mpctx_get_video_out(guiIntfStruct.mpcontext); | |
563 mixer = mpctx_get_mixer(guiIntfStruct.mpcontext); | |
564 } | |
565 | |
566 switch ( type ) | |
567 { | |
568 case guiXEvent: | |
569 guiIntfStruct.event_struct=(void *)arg; | |
570 wsEvents( wsDisplay,(XEvent *)arg,NULL ); | |
571 gtkEventHandling(); | |
572 break; | |
573 case guiCEvent: | |
574 switch ( (int)arg ) | |
575 { | |
576 case guiSetPlay: | |
577 guiIntfStruct.Playing=1; | |
578 // if ( !gtkShowVideoWindow ) wsVisibleWindow( &appMPlayer.subWindow,wsHideWindow ); | |
579 break; | |
580 case guiSetStop: | |
581 guiIntfStruct.Playing=0; | |
582 // if ( !gtkShowVideoWindow ) wsVisibleWindow( &appMPlayer.subWindow,wsHideWindow ); | |
583 break; | |
584 case guiSetPause: guiIntfStruct.Playing=2; break; | |
585 } | |
586 mplState(); | |
587 break; | |
588 case guiSetState: | |
589 mplState(); | |
590 break; | |
591 case guiSetFileName: | |
592 if ( arg ) guiSetFilename( guiIntfStruct.Filename,arg ); | |
593 break; | |
594 case guiSetAudioOnly: | |
595 guiIntfStruct.AudioOnly=(int)arg; | |
596 if ( (int)arg ) { guiIntfStruct.NoWindow=True; wsVisibleWindow( &appMPlayer.subWindow,wsHideWindow ); } | |
597 else wsVisibleWindow( &appMPlayer.subWindow,wsShowWindow ); | |
598 break; | |
599 case guiSetContext: | |
600 guiIntfStruct.mpcontext=(void *)arg; | |
601 case guiSetDemuxer: | |
602 guiIntfStruct.demuxer=(void *)arg; | |
603 break; | |
604 case guiSetAfilter: | |
605 guiIntfStruct.afilter=(void *)arg; | |
606 break; | |
607 case guiSetShVideo: | |
608 { | |
609 if ( !appMPlayer.subWindow.isFullScreen ) | |
610 { | |
611 wsResizeWindow( &appMPlayer.subWindow,vo_dwidth,vo_dheight ); | |
612 wsMoveWindow( &appMPlayer.subWindow,True,appMPlayer.sub.x,appMPlayer.sub.y ); | |
613 } | |
614 guiIntfStruct.MovieWidth=vo_dwidth; | |
615 guiIntfStruct.MovieHeight=vo_dheight; | |
616 if (guiWinID>=0) | |
617 wsMoveWindow( &appMPlayer.mainWindow,0,0, vo_dheight); | |
618 } | |
619 break; | |
620 #ifdef USE_DVDREAD | |
621 case guiSetDVD: | |
622 guiIntfStruct.DVD.titles=dvdp->vmg_file->tt_srpt->nr_of_srpts; | |
623 guiIntfStruct.DVD.chapters=dvdp->vmg_file->tt_srpt->title[dvd_title].nr_of_ptts; | |
624 guiIntfStruct.DVD.angles=dvdp->vmg_file->tt_srpt->title[dvd_title].nr_of_angles; | |
625 guiIntfStruct.DVD.nr_of_audio_channels=dvdp->nr_of_channels; | |
626 memcpy( guiIntfStruct.DVD.audio_streams,dvdp->audio_streams,sizeof( dvdp->audio_streams ) ); | |
627 guiIntfStruct.DVD.nr_of_subtitles=dvdp->nr_of_subtitles; | |
628 memcpy( guiIntfStruct.DVD.subtitles,dvdp->subtitles,sizeof( dvdp->subtitles ) ); | |
629 guiIntfStruct.DVD.current_title=dvd_title + 1; | |
630 guiIntfStruct.DVD.current_chapter=dvd_chapter + 1; | |
631 guiIntfStruct.DVD.current_angle=dvd_angle + 1; | |
632 guiIntfStruct.Track=dvd_title + 1; | |
633 break; | |
634 #endif | |
635 case guiSetStream: | |
636 guiIntfStruct.StreamType=stream->type; | |
637 switch( stream->type ) | |
638 { | |
639 #ifdef USE_DVDREAD | |
640 case STREAMTYPE_DVD: | |
641 guiGetEvent( guiSetDVD,(char *)stream->priv ); | |
642 break; | |
643 #endif | |
644 #ifdef HAVE_VCD | |
645 case STREAMTYPE_VCD: | |
646 { | |
647 int i; | |
648 | |
649 if (!stream->priv) | |
650 { | |
651 guiIntfStruct.VCDTracks=0; | |
652 break; | |
653 } | |
654 for ( i=1;i < 100;i++ ) | |
655 if ( vcd_seek_to_track( stream->priv,i ) < 0 ) break; | |
656 vcd_seek_to_track( stream->priv,vcd_track ); | |
657 guiIntfStruct.VCDTracks=--i; | |
658 break; | |
659 } | |
660 #endif | |
661 default: break; | |
662 } | |
663 break; | |
664 case guiIEvent: | |
665 mp_msg( MSGT_GPLAYER,MSGL_V,"cmd: %d\n",(int)arg ); | |
666 switch( (int)arg ) | |
667 { | |
668 case MP_CMD_QUIT: | |
669 mplEventHandling( evExit,0 ); | |
670 break; | |
671 case MP_CMD_VO_FULLSCREEN: | |
672 mplEventHandling( evFullScreen,0 ); | |
673 break; | |
674 default: | |
675 mplEventHandling( guiCMDArray[ (int)arg - MP_CMD_GUI_EVENTS - 1 ],0 ); | |
676 } | |
677 break; | |
678 case guiReDraw: | |
679 mplEventHandling( evRedraw,0 ); | |
680 break; | |
681 case guiSetVolume: | |
682 if ( audio_out ) | |
683 { | |
684 float l,r; | |
685 mixer_getvolume( mixer,&l,&r ); | |
686 guiIntfStruct.Volume=(r>l?r:l); | |
687 if ( r != l ) guiIntfStruct.Balance=( ( r - l ) + 100 ) * 0.5f; | |
688 else guiIntfStruct.Balance=50.0f; | |
689 btnModify( evSetVolume,guiIntfStruct.Volume ); | |
690 btnModify( evSetBalance,guiIntfStruct.Balance ); | |
691 } | |
692 break; | |
693 case guiSetFileFormat: | |
694 guiIntfStruct.FileFormat=(int)arg; | |
695 break; | |
696 case guiSetValues: | |
697 // -- video | |
698 guiIntfStruct.sh_video=arg; | |
699 if ( arg ) | |
700 { | |
701 sh_video_t * sh = (sh_video_t *)arg; | |
702 guiIntfStruct.FPS=sh->fps; | |
703 } | |
704 | |
705 if ( guiIntfStruct.NoWindow ) wsVisibleWindow( &appMPlayer.subWindow,wsHideWindow ); | |
706 | |
707 if ( guiIntfStruct.StreamType == STREAMTYPE_STREAM ) btnSet( evSetMoviePosition,btnDisabled ); | |
708 else btnSet( evSetMoviePosition,btnReleased ); | |
709 | |
710 // -- audio | |
711 if ( audio_out ) | |
712 { | |
713 float l,r; | |
714 mixer_getvolume( mixer,&l,&r ); | |
715 guiIntfStruct.Volume=(r>l?r:l); | |
716 if ( r != l ) guiIntfStruct.Balance=( ( r - l ) + 100 ) * 0.5f; | |
717 else guiIntfStruct.Balance=50.0f; | |
718 btnModify( evSetVolume,guiIntfStruct.Volume ); | |
719 btnModify( evSetBalance,guiIntfStruct.Balance ); | |
720 } | |
721 | |
722 if ( gtkEnableAudioEqualizer ) | |
723 { | |
724 equalizer_t eq; | |
725 int i,j; | |
726 for ( i=0;i<6;i++ ) | |
727 for ( j=0;j<10;j++ ) | |
728 { | |
729 eq.channel=i; eq.band=j; eq.gain=gtkEquChannels[i][j]; | |
730 gtkSet( gtkSetEqualizer,0,&eq ); | |
731 } | |
732 } | |
733 // -- subtitle | |
734 #ifdef HAVE_DXR3 | |
735 if ( video_driver_list && !gstrcmp( video_driver_list[0],"dxr3" ) && guiIntfStruct.FileFormat != DEMUXER_TYPE_MPEG_PS | |
736 #ifdef USE_LIBAVCODEC | |
737 && !gtkVfLAVC | |
738 #endif | |
739 ) | |
740 { | |
741 gtkMessageBox( GTK_MB_FATAL,MSGTR_NEEDLAVC ); | |
742 guiIntfStruct.Playing=0; | |
743 return True; | |
744 } | |
745 #endif | |
746 break; | |
747 case guiSetDefaults: | |
748 // if ( guiIntfStruct.Playing == 1 && guiIntfStruct.FilenameChanged ) | |
749 if ( guiIntfStruct.FilenameChanged ) | |
750 { | |
751 audio_id=-1; | |
752 video_id=-1; | |
753 dvdsub_id=-1; | |
754 vobsub_id=-1; | |
755 stream_cache_size=-1; | |
756 autosync=0; | |
757 vcd_track=0; | |
758 dvd_title=0; | |
759 force_fps=0; | |
760 } | |
761 guiIntfStruct.demuxer=NULL; | |
762 guiIntfStruct.sh_video=NULL; | |
763 wsPostRedisplay( &appMPlayer.subWindow ); | |
764 break; | |
765 case guiSetParameters: | |
766 guiGetEvent( guiSetDefaults,NULL ); | |
767 switch ( guiIntfStruct.StreamType ) | |
768 { | |
769 case STREAMTYPE_PLAYLIST: | |
770 break; | |
771 #ifdef HAVE_VCD | |
772 case STREAMTYPE_VCD: | |
773 { | |
774 char tmp[512]; | |
775 sprintf( tmp,"vcd://%d",guiIntfStruct.Track + 1 ); | |
776 guiSetFilename( guiIntfStruct.Filename,tmp ); | |
777 } | |
778 break; | |
779 #endif | |
780 #ifdef USE_DVDREAD | |
781 case STREAMTYPE_DVD: | |
782 { | |
783 char tmp[512]; | |
784 sprintf( tmp,"dvd://%d",guiIntfStruct.Title ); | |
785 guiSetFilename( guiIntfStruct.Filename,tmp ); | |
786 } | |
787 dvd_chapter=guiIntfStruct.Chapter; | |
788 dvd_angle=guiIntfStruct.Angle; | |
789 break; | |
790 #endif | |
791 } | |
792 //if ( guiIntfStruct.StreamType != STREAMTYPE_PLAYLIST ) // Does not make problems anymore! | |
793 { | |
794 if ( guiIntfStruct.Filename ) filename=gstrdup( guiIntfStruct.Filename ); | |
795 else if ( filename ) guiSetFilename( guiIntfStruct.Filename,filename ); | |
796 } | |
797 // --- video opts | |
798 | |
799 if ( !video_driver_list ) | |
800 { | |
801 int i = 0; | |
802 while ( video_out_drivers[i++] ) | |
803 if ( video_out_drivers[i - 1]->control( VOCTRL_GUISUPPORT,NULL ) == VO_TRUE ) | |
804 { | |
805 gaddlist( &video_driver_list,(char *)video_out_drivers[i - 1]->info->short_name ); | |
806 break; | |
807 } | |
808 } | |
809 | |
810 if ( !video_driver_list && !video_driver_list[0] ) { gtkMessageBox( GTK_MB_FATAL,MSGTR_IDFGCVD ); exit_player( "gui init" ); } | |
811 | |
812 { | |
813 int i = 0; | |
814 guiIntfStruct.NoWindow=False; | |
815 while ( video_out_drivers[i++] ) | |
816 if ( video_out_drivers[i - 1]->control( VOCTRL_GUISUPPORT,NULL ) == VO_TRUE ) | |
817 { | |
818 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 ) ) | |
819 { guiIntfStruct.NoWindow=True; break; } | |
820 } | |
821 } | |
822 | |
823 #ifdef HAVE_DXR3 | |
824 #ifdef USE_LIBAVCODEC | |
825 remove_vf( "lavc" ); | |
826 #endif | |
827 if ( video_driver_list && !gstrcmp( video_driver_list[0],"dxr3" ) ) | |
828 { | |
829 if ( ( guiIntfStruct.StreamType != STREAMTYPE_DVD)&&( guiIntfStruct.StreamType != STREAMTYPE_VCD ) ) | |
830 { | |
831 #ifdef USE_LIBAVCODEC | |
832 if ( gtkVfLAVC ) add_vf( "lavc" ); | |
833 #endif | |
834 } | |
835 } | |
836 #endif | |
837 // --- | |
838 if ( gtkVfPP ) add_vf( "pp" ); | |
839 else remove_vf( "pp" ); | |
840 | |
841 // --- audio opts | |
842 // if ( ao_plugin_cfg.plugin_list ) { free( ao_plugin_cfg.plugin_list ); ao_plugin_cfg.plugin_list=NULL; } | |
843 if (gtkAONorm) | |
844 greplace(&af_cfg.list, "volnorm", "volnorm"); | |
845 if (gtkEnableAudioEqualizer) | |
846 greplace(&af_cfg.list, "equalizer", "equalizer"); | |
847 if ( gtkAOExtraStereo ) | |
848 { | |
849 char *name = malloc(12 + 20 + 1); | |
850 snprintf(name, 12 + 20, "extrastereo=%f", gtkAOExtraStereoMul); | |
851 name[12 + 20] = 0; | |
852 greplace(&af_cfg.list, "extrastereo", name); | |
853 free(name); | |
854 } | |
855 #ifdef USE_OSS_AUDIO | |
856 if ( audio_driver_list && !gstrncmp( audio_driver_list[0],"oss",3 ) ) | |
857 { | |
858 char *tmp; | |
859 mixer_device = gtkAOOSSMixer; | |
860 mixer_channel = gtkAOOSSMixerChannel; | |
861 if (gtkAOOSSDevice) { | |
862 tmp = calloc( 1,strlen( gtkAOOSSDevice ) + 7 ); | |
863 sprintf( tmp,"oss:%s",gtkAOOSSDevice ); | |
864 } else | |
865 tmp = strdup("oss"); | |
866 gaddlist( &audio_driver_list,tmp ); | |
867 free(tmp); | |
868 } | |
869 #endif | |
870 #if defined(HAVE_ALSA9) || defined (HAVE_ALSA1X) | |
871 if ( audio_driver_list && !gstrncmp( audio_driver_list[0],"alsa",4 ) ) | |
872 { | |
873 char *tmp; | |
874 mixer_device = gtkAOALSAMixer; | |
875 mixer_channel = gtkAOALSAMixerChannel; | |
876 if (gtkAOALSADevice) { | |
877 tmp = calloc( 1,strlen( gtkAOALSADevice ) + 14 ); | |
878 sprintf( tmp,"alsa:device=%s",gtkAOALSADevice ); | |
879 } else | |
880 tmp = strdup("alsa"); | |
881 gaddlist( &audio_driver_list,tmp ); | |
882 free(tmp); | |
883 } | |
884 #endif | |
885 #ifdef HAVE_SDL | |
886 if ( audio_driver_list && !gstrncmp( audio_driver_list[0],"sdl",3 ) ) | |
887 { | |
888 char *tmp; | |
889 if (gtkAOSDLDriver) { | |
890 tmp = calloc( 1,strlen( gtkAOSDLDriver ) + 10 ); | |
891 sprintf( tmp,"sdl:%s",gtkAOSDLDriver ); | |
892 } else | |
893 tmp = strdup("sdl"); | |
894 gaddlist( &audio_driver_list,tmp ); | |
895 free(tmp); | |
896 } | |
897 #endif | |
898 #ifdef USE_ESD | |
899 if ( audio_driver_list && !gstrncmp( audio_driver_list[0],"esd",3 ) ) | |
900 { | |
901 char *tmp; | |
902 if (gtkAOESDDevice) { | |
903 tmp = calloc( 1,strlen( gtkAOESDDevice ) + 10 ); | |
904 sprintf( tmp,"esd:%s",gtkAOESDDevice ); | |
905 } else | |
906 tmp = strdup("esd"); | |
907 gaddlist( &audio_driver_list,tmp ); | |
908 free(tmp); | |
909 } | |
910 #endif | |
911 // -- subtitle | |
912 //subdata->filename=gstrdup( guiIntfStruct.Subtitlename ); | |
913 stream_dump_type=0; | |
914 if ( gtkSubDumpMPSub ) stream_dump_type=4; | |
915 if ( gtkSubDumpSrt ) stream_dump_type=6; | |
916 gtkSubDumpMPSub=gtkSubDumpSrt=0; | |
917 guiLoadFont(); | |
918 | |
919 // --- misc | |
920 if ( gtkCacheOn ) stream_cache_size=gtkCacheSize; | |
921 if ( gtkAutoSyncOn ) autosync=gtkAutoSync; | |
922 | |
923 if ( guiIntfStruct.AudioFile ) audio_stream=gstrdup( guiIntfStruct.AudioFile ); | |
924 else if ( guiIntfStruct.FilenameChanged ) gfree( (void**)&audio_stream ); | |
925 //audio_stream=NULL; | |
926 | |
927 guiIntfStruct.DiskChanged=0; | |
928 guiIntfStruct.FilenameChanged=0; | |
929 guiIntfStruct.NewPlay=0; | |
930 | |
931 #ifdef USE_ASS | |
932 ass_enabled = gtkASS.enabled; | |
933 ass_use_margins = gtkASS.use_margins; | |
934 ass_top_margin = gtkASS.top_margin; | |
935 ass_bottom_margin = gtkASS.bottom_margin; | |
936 #endif | |
937 | |
938 break; | |
939 } | |
940 return False; | |
941 } | |
942 | |
943 void guiEventHandling( void ) | |
944 { | |
945 if ( !guiIntfStruct.Playing || guiIntfStruct.NoWindow ) wsHandleEvents(); | |
946 gtkEventHandling(); | |
947 } | |
948 | |
949 // --- | |
950 | |
951 float gtkEquChannels[6][10]; | |
952 | |
953 plItem * plCurrent = NULL; | |
954 plItem * plList = NULL; | |
955 plItem * plLastPlayed = NULL; | |
956 | |
957 URLItem *URLList = NULL; | |
958 | |
959 char *fsHistory[fsPersistant_MaxPos] = { NULL,NULL,NULL,NULL,NULL }; | |
960 | |
961 #if defined( MP_DEBUG ) && 0 | |
962 void list( void ) | |
963 { | |
964 plItem * next = plList; | |
965 printf( "--- list ---\n" ); | |
966 while( next || next->next ) | |
967 { | |
968 printf( "item: %s/%s\n",next->path,next->name ); | |
969 if ( next->next ) next=next->next; else break; | |
970 } | |
971 printf( "--- end of list ---\n" ); | |
972 } | |
973 #else | |
974 #define list(); | |
975 #endif | |
976 | |
977 void * gtkSet( int cmd,float fparam, void * vparam ) | |
978 { | |
979 equalizer_t * eq = (equalizer_t *)vparam; | |
980 plItem * item = (plItem *)vparam; | |
981 | |
982 URLItem * url_item = (URLItem *)vparam; | |
983 int is_added = True; | |
984 | |
985 switch ( cmd ) | |
986 { | |
987 // --- handle playlist | |
988 case gtkAddPlItem: // add item to playlist | |
989 if ( plList ) | |
990 { | |
991 plItem * next = plList; | |
992 while ( next->next ) { /*printf( "%s\n",next->name );*/ next=next->next; } | |
993 next->next=item; item->prev=next; | |
994 } else { item->prev=item->next=NULL; plCurrent=plList=item; } | |
995 list(); | |
996 return NULL; | |
997 case gtkInsertPlItem: // add item into playlist after current | |
998 if ( plCurrent ) | |
999 { | |
1000 plItem * curr = plCurrent; | |
1001 item->next=curr->next; | |
1002 if (item->next) | |
1003 item->next->prev=item; | |
1004 item->prev=curr; | |
1005 curr->next=item; | |
1006 plCurrent=plCurrent->next; | |
1007 return plCurrent; | |
1008 } | |
1009 else | |
1010 return gtkSet(gtkAddPlItem,0,(void*)item); | |
1011 return NULL; | |
1012 case gtkGetNextPlItem: // get current item from playlist | |
1013 if ( plCurrent && plCurrent->next) | |
1014 { | |
1015 plCurrent=plCurrent->next; | |
1016 /*if ( !plCurrent && plList ) | |
1017 { | |
1018 plItem * next = plList; | |
1019 while ( next->next ) { if ( !next->next ) break; next=next->next; } | |
1020 plCurrent=next; | |
1021 }*/ | |
1022 return plCurrent; | |
1023 } | |
1024 return NULL; | |
1025 case gtkGetPrevPlItem: | |
1026 if ( plCurrent && plCurrent->prev) | |
1027 { | |
1028 plCurrent=plCurrent->prev; | |
1029 //if ( !plCurrent && plList ) plCurrent=plList; | |
1030 return plCurrent; | |
1031 } | |
1032 return NULL; | |
1033 case gtkSetCurrPlItem: // set current item | |
1034 plCurrent=item; | |
1035 return plCurrent; | |
1036 case gtkGetCurrPlItem: // get current item | |
1037 return plCurrent; | |
1038 case gtkDelCurrPlItem: // delete current item | |
1039 { | |
1040 plItem * curr = plCurrent; | |
1041 | |
1042 if (!curr) | |
1043 return NULL; | |
1044 if (curr->prev) | |
1045 curr->prev->next=curr->next; | |
1046 if (curr->next) | |
1047 curr->next->prev=curr->prev; | |
1048 if (curr==plList) | |
1049 plList=curr->next; | |
1050 plCurrent=curr->next; | |
1051 // Free it | |
1052 if ( curr->path ) free( curr->path ); | |
1053 if ( curr->name ) free( curr->name ); | |
1054 free( curr ); | |
1055 } | |
1056 mplCurr(); // Instead of using mplNext && mplPrev | |
1057 | |
1058 return plCurrent; | |
1059 case gtkDelPl: // delete list | |
1060 { | |
1061 plItem * curr = plList; | |
1062 plItem * next; | |
1063 if ( !plList ) return NULL; | |
1064 if ( !curr->next ) | |
1065 { | |
1066 if ( curr->path ) free( curr->path ); | |
1067 if ( curr->name ) free( curr->name ); | |
1068 free( curr ); | |
1069 } | |
1070 else | |
1071 { | |
1072 while ( curr->next ) | |
1073 { | |
1074 next=curr->next; | |
1075 if ( curr->path ) free( curr->path ); | |
1076 if ( curr->name ) free( curr->name ); | |
1077 free( curr ); | |
1078 curr=next; | |
1079 } | |
1080 } | |
1081 plList=NULL; plCurrent=NULL; | |
1082 } | |
1083 return NULL; | |
1084 // ----- Handle url | |
1085 case gtkAddURLItem: | |
1086 if ( URLList ) | |
1087 { | |
1088 URLItem * next_url = URLList; | |
1089 is_added = False; | |
1090 while ( next_url->next ) | |
1091 { | |
1092 if ( !gstrcmp( next_url->url,url_item->url ) ) | |
1093 { | |
1094 is_added=True; | |
1095 break; | |
1096 } | |
1097 next_url=next_url->next; | |
1098 } | |
1099 if ( ( !is_added )&&( gstrcmp( next_url->url,url_item->url ) ) ) next_url->next=url_item; | |
1100 } else { url_item->next=NULL; URLList=url_item; } | |
1101 return NULL; | |
1102 // --- subtitle | |
1103 #ifndef HAVE_FREETYPE | |
1104 case gtkSetFontFactor: | |
1105 font_factor=fparam; | |
1106 guiLoadFont(); | |
1107 return NULL; | |
1108 #else | |
1109 case gtkSetFontOutLine: | |
1110 subtitle_font_thickness=( 8.0f / 100.0f ) * fparam; | |
1111 guiLoadFont(); | |
1112 return NULL; | |
1113 case gtkSetFontBlur: | |
1114 subtitle_font_radius=( 8.0f / 100.0f ) * fparam; | |
1115 guiLoadFont(); | |
1116 return NULL; | |
1117 case gtkSetFontTextScale: | |
1118 text_font_scale_factor=fparam; | |
1119 guiLoadFont(); | |
1120 return NULL; | |
1121 case gtkSetFontOSDScale: | |
1122 osd_font_scale_factor=fparam; | |
1123 guiLoadFont(); | |
1124 return NULL; | |
1125 case gtkSetFontEncoding: | |
1126 gfree( (void **)&subtitle_font_encoding ); | |
1127 subtitle_font_encoding=gstrdup( (char *)vparam ); | |
1128 guiLoadFont(); | |
1129 return NULL; | |
1130 case gtkSetFontAutoScale: | |
1131 subtitle_autoscale=(int)fparam; | |
1132 guiLoadFont(); | |
1133 return NULL; | |
1134 #endif | |
1135 #ifdef USE_ICONV | |
1136 case gtkSetSubEncoding: | |
1137 gfree( (void **)&sub_cp ); | |
1138 sub_cp=gstrdup( (char *)vparam ); | |
1139 break; | |
1140 #endif | |
1141 // --- misc | |
1142 case gtkClearStruct: | |
1143 if ( (unsigned int)vparam & guiFilenames ) | |
1144 { | |
1145 gfree( (void **)&guiIntfStruct.Filename ); | |
1146 gfree( (void **)&guiIntfStruct.Subtitlename ); | |
1147 gfree( (void **)&guiIntfStruct.AudioFile ); | |
1148 gtkSet( gtkDelPl,0,NULL ); | |
1149 } | |
1150 #ifdef USE_DVDREAD | |
1151 if ( (unsigned int)vparam & guiDVD ) memset( &guiIntfStruct.DVD,0,sizeof( guiDVDStruct ) ); | |
1152 #endif | |
1153 #ifdef HAVE_VCD | |
1154 if ( (unsigned int)vparam & guiVCD ) guiIntfStruct.VCDTracks=0; | |
1155 #endif | |
1156 return NULL; | |
1157 case gtkSetExtraStereo: | |
1158 gtkAOExtraStereoMul=fparam; | |
1159 if (guiIntfStruct.afilter) | |
1160 af_control_any_rev(guiIntfStruct.afilter, | |
1161 AF_CONTROL_ES_MUL | AF_CONTROL_SET, >kAOExtraStereoMul); | |
1162 return NULL; | |
1163 case gtkSetPanscan: | |
1164 { | |
1165 mp_cmd_t * mp_cmd; | |
1166 mp_cmd=calloc( 1,sizeof( *mp_cmd ) ); | |
1167 mp_cmd->id=MP_CMD_PANSCAN; mp_cmd->name=strdup( "panscan" ); | |
1168 mp_cmd->args[0].v.f=fparam; mp_cmd->args[1].v.i=1; | |
1169 mp_input_queue_cmd( mp_cmd ); | |
1170 } | |
1171 return NULL; | |
1172 case gtkSetAutoq: | |
1173 auto_quality=(int)fparam; | |
1174 return NULL; | |
1175 // --- set equalizers | |
1176 case gtkSetContrast: | |
1177 if ( guiIntfStruct.sh_video ) set_video_colors( guiIntfStruct.sh_video,"contrast",(int)fparam ); | |
1178 return NULL; | |
1179 case gtkSetBrightness: | |
1180 if ( guiIntfStruct.sh_video ) set_video_colors( guiIntfStruct.sh_video,"brightness",(int)fparam ); | |
1181 return NULL; | |
1182 case gtkSetHue: | |
1183 if ( guiIntfStruct.sh_video ) set_video_colors( guiIntfStruct.sh_video,"hue",(int)fparam ); | |
1184 return NULL; | |
1185 case gtkSetSaturation: | |
1186 if ( guiIntfStruct.sh_video ) set_video_colors( guiIntfStruct.sh_video,"saturation",(int)fparam ); | |
1187 return NULL; | |
1188 case gtkSetEqualizer: | |
1189 { | |
1190 af_control_ext_t tmp; | |
1191 if ( eq ) | |
1192 { | |
1193 gtkEquChannels[eq->channel][eq->band]=eq->gain; | |
1194 tmp.ch = eq->channel; | |
1195 tmp.arg = gtkEquChannels[eq->channel]; | |
1196 if (guiIntfStruct.afilter) | |
1197 af_control_any_rev(guiIntfStruct.afilter, | |
1198 AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_SET, &tmp); | |
1199 } | |
1200 else | |
1201 { | |
1202 int i; | |
1203 memset( gtkEquChannels,0,sizeof( gtkEquChannels ) ); | |
1204 if (guiIntfStruct.afilter) | |
1205 for ( i=0;i<6;i++ ) | |
1206 { | |
1207 tmp.ch = i; | |
1208 tmp.arg = gtkEquChannels[i]; | |
1209 af_control_any_rev(guiIntfStruct.afilter, | |
1210 AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_SET, &tmp); | |
1211 } | |
1212 } | |
1213 return NULL; | |
1214 } | |
1215 } | |
1216 return NULL; | |
1217 } | |
1218 | |
1219 #define mp_basename(s) (strrchr(s,'/')==NULL?(char*)s:(strrchr(s,'/')+1)) | |
1220 | |
1221 #include "playtree.h" | |
1222 | |
1223 //This function adds/inserts one file into the gui playlist | |
1224 | |
1225 int import_file_into_gui(char* temp, int insert) | |
1226 { | |
1227 char *filename, *pathname; | |
1228 plItem * item; | |
1229 | |
1230 filename = strdup(mp_basename(temp)); | |
1231 pathname = strdup(temp); | |
1232 if (strlen(pathname)-strlen(filename)>0) | |
1233 pathname[strlen(pathname)-strlen(filename)-1]='\0'; // We have some path so remove / at end | |
1234 else | |
1235 pathname[strlen(pathname)-strlen(filename)]='\0'; | |
1236 mp_msg(MSGT_PLAYTREE,MSGL_V, "Adding filename %s && pathname %s\n",filename,pathname); //FIXME: Change to MSGL_DBG2 ? | |
1237 item=calloc( 1,sizeof( plItem ) ); | |
1238 if (!item) | |
1239 return 0; | |
1240 item->name=filename; | |
1241 item->path=pathname; | |
1242 if (insert) | |
1243 gtkSet( gtkInsertPlItem,0,(void*)item ); // Inserts the item after current, and makes current=item | |
1244 else | |
1245 gtkSet( gtkAddPlItem,0,(void*)item ); | |
1246 return 1; | |
1247 } | |
1248 | |
1249 | |
1250 // This function imports the initial playtree (based on cmd-line files) into the gui playlist | |
1251 // by either: | |
1252 // - overwriting gui pl (enqueue=0) | |
1253 // - appending it to gui pl (enqueue=1) | |
1254 | |
1255 int import_initial_playtree_into_gui(play_tree_t* my_playtree, m_config_t* config, int enqueue) | |
1256 { | |
1257 play_tree_iter_t* my_pt_iter=NULL; | |
1258 int result=0; | |
1259 | |
1260 if (!enqueue) // Delete playlist before "appending" | |
1261 gtkSet(gtkDelPl,0,0); | |
1262 | |
1263 if((my_pt_iter=pt_iter_create(&my_playtree,config))) | |
1264 { | |
1265 while ((filename=pt_iter_get_next_file(my_pt_iter))!=NULL) | |
1266 { | |
1267 if (import_file_into_gui(filename, 0)) // Add it to end of list | |
1268 result=1; | |
1269 } | |
1270 } | |
1271 | |
1272 mplCurr(); // Update filename | |
1273 mplGotoTheNext=1; | |
1274 | |
1275 if (!enqueue) | |
1276 filename=guiIntfStruct.Filename; // Backward compatibility; if file is specified on commandline, | |
1277 // gmplayer does directly start in Play-Mode. | |
1278 else | |
1279 filename=NULL; | |
1280 | |
1281 return result; | |
1282 } | |
1283 | |
1284 // This function imports and inserts an playtree, that is created "on the fly", for example by | |
1285 // parsing some MOV-Reference-File; or by loading an playlist with "File Open" | |
1286 // | |
1287 // The file which contained the playlist is thereby replaced with it's contents. | |
1288 | |
1289 int import_playtree_playlist_into_gui(play_tree_t* my_playtree, m_config_t* config) | |
1290 { | |
1291 play_tree_iter_t* my_pt_iter=NULL; | |
1292 int result=0; | |
1293 plItem * save=(plItem*)gtkSet( gtkGetCurrPlItem, 0, 0); // Save current item | |
1294 | |
1295 if((my_pt_iter=pt_iter_create(&my_playtree,config))) | |
1296 { | |
1297 while ((filename=pt_iter_get_next_file(my_pt_iter))!=NULL) | |
1298 { | |
1299 if (import_file_into_gui(filename, 1)) // insert it into the list and set plCurrent=new item | |
1300 result=1; | |
1301 } | |
1302 pt_iter_destroy(&my_pt_iter); | |
1303 } | |
1304 | |
1305 if (save) | |
1306 gtkSet(gtkSetCurrPlItem, 0, (void*)save); | |
1307 else | |
1308 gtkSet(gtkSetCurrPlItem, 0, (void*)plList); // go to head, if plList was empty before | |
1309 | |
1310 if (save && result) | |
1311 gtkSet(gtkDelCurrPlItem, 0, 0); | |
1312 | |
1313 mplCurr(); // Update filename | |
1314 filename=NULL; | |
1315 | |
1316 return result; | |
1317 } | |
1318 | |
1319 // wrapper function for mp_msg to display a message box for errors and warnings. | |
1320 | |
1321 void guiMessageBox(int level, char * str) { | |
1322 switch(level) { | |
1323 case MSGL_FATAL: | |
1324 gtkMessageBox(GTK_MB_FATAL|GTK_MB_SIMPLE, str); | |
1325 break; | |
1326 case MSGL_ERR: | |
1327 gtkMessageBox(GTK_MB_ERROR|GTK_MB_SIMPLE, str); | |
1328 break; | |
1329 #if 0 | |
1330 // WARNING! Do NOT enable this! There are too many non-critical messages with | |
1331 // MSGL_WARN, for example: broken SPU packets, codec's bit error messages, | |
1332 // etc etc, they should not raise up a new window every time. | |
1333 case MSGL_WARN: | |
1334 gtkMessageBox(GTK_MB_WARNING|GTK_MB_SIMPLE, str); | |
1335 break; | |
1336 #endif | |
1337 } | |
1338 } |