4 * This file is part of MPlayer.
6 * MPlayer is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * MPlayer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "gui/skin/font.h"
32 #include "gui/skin/skin.h"
33 #include "gui/wm/ws.h"
36 #include "libvo/x11_common.h"
37 #include "libvo/fastmemcpy.h"
39 #include "stream/stream.h"
40 #include "stream/url.h"
42 #include "libvo/sub.h"
43 #include "access_mpcontext.h"
45 #include "libmpdemux/demuxer.h"
46 #include "libmpdemux/stheader.h"
47 #include "codec-cfg.h"
49 #include "m_property.h"
51 #define GUI_REDRAW_WAIT 375
56 unsigned int GetTimerMS( void );
58 unsigned char * mplDrawBuffer
= NULL
;
59 int mplMainRender
= 1;
61 int mplMainAutoPlay
= 0;
62 int mplMiddleMenu
= 0;
70 #include "gui_common.h"
72 void mplMainDraw( void )
75 if ( appMPlayer
.mainWindow
.State
== wsWindowClosed
) exit_player( MSGTR_Exit_quit
);
77 if ( appMPlayer
.mainWindow
.Visible
== wsWindowNotVisible
||
78 !mainVisible
) return;
79 // !appMPlayer.mainWindow.Mapped ) return;
81 if ( mplMainRender
&& appMPlayer
.mainWindow
.State
== wsWindowExpose
)
83 btnModify( evSetMoviePosition
,guiIntfStruct
.Position
);
84 btnModify( evSetVolume
,guiIntfStruct
.Volume
);
86 fast_memcpy( mplDrawBuffer
,appMPlayer
.main
.Bitmap
.Image
,appMPlayer
.main
.Bitmap
.ImageSize
);
87 Render( &appMPlayer
.mainWindow
,appMPlayer
.Items
,appMPlayer
.NumberOfItems
,mplDrawBuffer
,appMPlayer
.main
.Bitmap
.ImageSize
);
90 wsPutImage( &appMPlayer
.mainWindow
);
91 // XFlush( wsDisplay );
94 static unsigned last_redraw_time
= 0;
96 void mplEventHandling( int msg
,float param
)
98 int iparam
= (int)param
;
99 mixer_t
*mixer
= mpctx_get_mixer(guiIntfStruct
.mpcontext
);
105 exit_player( "Exit" );
109 gfree( (void **)&guiIntfStruct
.Subtitlename
);
110 gfree( (void **)&guiIntfStruct
.AudioFile
);
111 guiIntfStruct
.StreamType
=STREAMTYPE_STREAM
;
114 gtkShow( evPlayNetwork
,NULL
);
118 if ( !guiIntfStruct
.demuxer
|| audio_id
== iparam
) break;
123 if ( !guiIntfStruct
.demuxer
|| video_id
== iparam
) break;
128 mp_property_do("sub",M_PROPERTY_SET
,&iparam
,guiIntfStruct
.mpcontext
);
133 guiIntfStruct
.Track
=iparam
;
135 gtkSet( gtkClearStruct
,0,(void *)guiALL
);
136 guiIntfStruct
.StreamType
=STREAMTYPE_VCD
;
139 #ifdef CONFIG_DVDREAD
141 guiIntfStruct
.DVD
.current_title
=1;
142 guiIntfStruct
.DVD
.current_chapter
=1;
143 guiIntfStruct
.DVD
.current_angle
=1;
145 gtkSet( gtkClearStruct
,0,(void *)(guiALL
- guiDVD
) );
146 guiIntfStruct
.StreamType
=STREAMTYPE_DVD
;
150 case evPlaySwitchToPause
:
153 if ( ( msg
== evPlaySwitchToPause
)&&( guiIntfStruct
.Playing
== 2 ) ) goto NoPause
;
155 if ( gtkSet( gtkGetCurrPlItem
,0,NULL
) &&( guiIntfStruct
.StreamType
== STREAMTYPE_FILE
) )
157 plItem
* next
= gtkSet( gtkGetCurrPlItem
,0,NULL
);
159 mplSetFileName( next
->path
,next
->name
,STREAMTYPE_FILE
);
162 switch ( guiIntfStruct
.StreamType
)
164 case STREAMTYPE_STREAM
:
165 case STREAMTYPE_FILE
:
166 gtkSet( gtkClearStruct
,0,(void *)(guiALL
- guiFilenames
) );
170 gtkSet( gtkClearStruct
,0,(void *)(guiALL
- guiVCD
- guiFilenames
) );
171 if ( !cdrom_device
) cdrom_device
=gstrdup( DEFAULT_CDROM_DEVICE
);
172 mplSetFileName( NULL
,cdrom_device
,STREAMTYPE_VCD
);
173 if ( guiIntfStruct
.Playing
!= 2 )
175 if ( !guiIntfStruct
.Track
)
177 if ( guiIntfStruct
.VCDTracks
> 1 ) guiIntfStruct
.Track
=2;
178 else guiIntfStruct
.Track
=1;
180 guiIntfStruct
.DiskChanged
=1;
184 #ifdef CONFIG_DVDREAD
186 gtkSet( gtkClearStruct
,0,(void *)(guiALL
- guiDVD
- guiFilenames
) );
187 if ( !dvd_device
) dvd_device
=gstrdup( DEFAULT_DVD_DEVICE
);
188 mplSetFileName( NULL
,dvd_device
,STREAMTYPE_DVD
);
189 if ( guiIntfStruct
.Playing
!= 2 )
191 guiIntfStruct
.Title
=guiIntfStruct
.DVD
.current_title
;
192 guiIntfStruct
.Chapter
=guiIntfStruct
.DVD
.current_chapter
;
193 guiIntfStruct
.Angle
=guiIntfStruct
.DVD
.current_angle
;
194 guiIntfStruct
.DiskChanged
=1;
199 guiIntfStruct
.NewPlay
=1;
202 #ifdef CONFIG_DVDREAD
203 case evSetDVDSubtitle
:
211 case evSetDVDChapter
:
212 guiIntfStruct
.DVD
.current_chapter
=iparam
;
216 guiIntfStruct
.DVD
.current_title
=iparam
;
217 guiIntfStruct
.DVD
.current_chapter
=1;
218 guiIntfStruct
.DVD
.current_angle
=1;
224 case evPauseSwitchToPlay
:
230 guiIntfStruct
.Playing
=guiSetStop
;
232 guiIntfStruct
.NoWindow
=False
;
237 // guiIntfStruct.StreamType=STREAMTYPE_FILE;
239 gtkSet( gtkDelPl
,0,NULL
);
240 gtkShow( evLoad
,NULL
);
242 case evLoadSubtitle
: gtkShow( evLoadSubtitle
,NULL
); break;
244 gfree( (void **)&guiIntfStruct
.Subtitlename
);
245 guiLoadSubtitle( NULL
);
247 case evLoadAudioFile
: gtkShow( evLoadAudioFile
,NULL
); break;
248 case evPrev
: mplPrev(); break;
249 case evNext
: mplNext(); break;
251 case evPlayList
: gtkShow( evPlayList
,NULL
); break;
252 case evSkinBrowser
: gtkShow( evSkinBrowser
,skinName
); break;
253 case evAbout
: gtkShow( evAbout
,NULL
); break;
254 case evPreferences
: gtkShow( evPreferences
,NULL
); break;
255 case evEqualizer
: gtkShow( evEqualizer
,NULL
); break;
257 case evForward10min
: mplRelSeek( 600 ); break;
258 case evBackward10min
: mplRelSeek( -600 );break;
259 case evForward1min
: mplRelSeek( 60 ); break;
260 case evBackward1min
: mplRelSeek( -60 ); break;
261 case evForward10sec
: mplRelSeek( 10 ); break;
262 case evBackward10sec
: mplRelSeek( -10 ); break;
263 case evSetMoviePosition
: mplAbsSeek( param
); break;
265 case evIncVolume
: vo_x11_putkey( wsGrayMul
); break;
266 case evDecVolume
: vo_x11_putkey( wsGrayDiv
); break;
267 case evMute
: mixer_mute( mixer
); break;
270 guiIntfStruct
.Volume
=param
;
273 guiIntfStruct
.Balance
=param
;
276 float l
= guiIntfStruct
.Volume
* ( ( 100.0 - guiIntfStruct
.Balance
) / 50.0 );
277 float r
= guiIntfStruct
.Volume
* ( ( guiIntfStruct
.Balance
) / 50.0 );
278 if ( l
> guiIntfStruct
.Volume
) l
=guiIntfStruct
.Volume
;
279 if ( r
> guiIntfStruct
.Volume
) r
=guiIntfStruct
.Volume
;
280 // printf( "!!! v: %.2f b: %.2f -> %.2f x %.2f\n",guiIntfStruct.Volume,guiIntfStruct.Balance,l,r );
281 mixer_setvolume( mixer
,l
,r
);
285 osd_visible
=(GetTimerMS() + 1000) | 1;
286 vo_osd_progbar_type
=OSD_VOLUME
;
287 vo_osd_progbar_value
=( ( guiIntfStruct
.Volume
) * 256.0 ) / 100.0;
288 vo_osd_changed( OSDTYPE_PROGBAR
);
296 case 0: wsIconify( appMPlayer
.mainWindow
); break;
297 case 1: wsIconify( appMPlayer
.subWindow
); break;
301 btnSet( evFullScreen
,btnReleased
);
302 if ( guiIntfStruct
.Playing
)
304 if ( appMPlayer
.subWindow
.isFullScreen
)
308 wsResizeWindow( &appMPlayer
.subWindow
, guiIntfStruct
.MovieWidth
/ 2, guiIntfStruct
.MovieHeight
/ 2 );
309 wsMoveWindow( &appMPlayer
.subWindow
, 0,
310 ( wsMaxX
- guiIntfStruct
.MovieWidth
/2 )/2 + wsOrgX
,
311 ( wsMaxY
- guiIntfStruct
.MovieHeight
/2 )/2 + wsOrgY
);
315 btnSet( evFullScreen
,btnReleased
);
316 if ( guiIntfStruct
.Playing
)
318 if ( appMPlayer
.subWindow
.isFullScreen
)
322 wsResizeWindow( &appMPlayer
.subWindow
, guiIntfStruct
.MovieWidth
* 2, guiIntfStruct
.MovieHeight
* 2 );
323 wsMoveWindow( &appMPlayer
.subWindow
, 0,
324 ( wsMaxX
- guiIntfStruct
.MovieWidth
*2 )/2 + wsOrgX
,
325 ( wsMaxY
- guiIntfStruct
.MovieHeight
*2 )/2 + wsOrgY
);
329 btnSet( evFullScreen
,btnReleased
);
330 if ( guiIntfStruct
.Playing
)
332 if ( appMPlayer
.subWindow
.isFullScreen
)
336 wsResizeWindow( &appMPlayer
.subWindow
, guiIntfStruct
.MovieWidth
, guiIntfStruct
.MovieHeight
);
337 wsMoveWindow( &appMPlayer
.subWindow
, 0,
338 ( wsMaxX
- guiIntfStruct
.MovieWidth
)/2 + wsOrgX
,
339 ( wsMaxY
- guiIntfStruct
.MovieHeight
)/2 + wsOrgY
);
341 } else if ( !appMPlayer
.subWindow
.isFullScreen
) break;
343 if ( !guiIntfStruct
.Playing
&& !gtkShowVideoWindow
) break;
345 if ( appMPlayer
.subWindow
.isFullScreen
) btnSet( evFullScreen
,btnPressed
);
346 else btnSet( evFullScreen
,btnReleased
);
352 case 2: movie_aspect
=16.0f
/ 9.0f
; break;
353 case 3: movie_aspect
=4.0f
/ 3.0f
; break;
354 case 4: movie_aspect
=2.35; break;
356 default: movie_aspect
=-1;
358 wsClearWindow( appMPlayer
.subWindow
);
359 #ifdef CONFIG_DVDREAD
360 if ( guiIntfStruct
.StreamType
== STREAMTYPE_DVD
|| guiIntfStruct
.StreamType
== STREAMTYPE_VCD
) goto play_dvd_2
;
363 guiIntfStruct
.NewPlay
=1;
369 unsigned now
= GetTimerMS();
370 extern int mplPBFade
;
371 if ((now
> last_redraw_time
) &&
372 (now
< last_redraw_time
+ GUI_REDRAW_WAIT
) &&
375 last_redraw_time
= now
;
378 wsPostRedisplay( &appMPlayer
.mainWindow
);
379 wsPostRedisplay( &appMPlayer
.barWindow
);
384 mp_msg( MSGT_GPLAYER
,MSGL_STATUS
,"[mw] event none received.\n" );
387 mp_msg( MSGT_GPLAYER
,MSGL_STATUS
,"[mw] unknown event received ( %d,%.2f ).\n",msg
,param
);
393 #define itPLMButton (itNULL - 1)
394 #define itPRMButton (itNULL - 2)
396 void mplMainMouseHandle( int Button
,int X
,int Y
,int RX
,int RY
)
398 static int itemtype
= 0;
403 static int SelectedItem
= -1;
404 int currentselected
= -1;
406 for ( i
=0;i
< appMPlayer
.NumberOfItems
+ 1;i
++ )
407 if ( ( appMPlayer
.Items
[i
].pressed
!= btnDisabled
)&&
408 ( wgIsRect( X
,Y
,appMPlayer
.Items
[i
].x
,appMPlayer
.Items
[i
].y
,appMPlayer
.Items
[i
].x
+appMPlayer
.Items
[i
].width
,appMPlayer
.Items
[i
].y
+appMPlayer
.Items
[i
].height
) ) )
409 { currentselected
=i
; break; }
413 case wsPMMouseButton
:
414 gtkShow( evHidePopUpMenu
,NULL
);
415 mplShowMenu( RX
,RY
);
416 itemtype
=itPRMButton
;
418 case wsRMMouseButton
:
419 mplHideMenu( RX
,RY
,0 );
422 case wsPLMouseButton
:
423 gtkShow( evHidePopUpMenu
,NULL
);
424 sx
=X
; sy
=Y
; boxMoved
=1; itemtype
=itPLMButton
;
425 SelectedItem
=currentselected
;
426 if ( SelectedItem
== -1 ) break;
428 item
=&appMPlayer
.Items
[SelectedItem
];
430 item
->pressed
=btnPressed
;
434 if ( ( SelectedItem
> -1 ) &&
435 ( ( ( item
->msg
== evPlaySwitchToPause
&& item
->msg
== evPauseSwitchToPlay
) ) ||
436 ( ( item
->msg
== evPauseSwitchToPlay
&& item
->msg
== evPlaySwitchToPause
) ) ) )
437 { item
->pressed
=btnDisabled
; }
441 case wsRLMouseButton
:
443 item
=&appMPlayer
.Items
[SelectedItem
];
444 item
->pressed
=btnReleased
;
446 if ( currentselected
== - 1 ) { itemtype
=0; break; }
452 btnModify( item
->msg
,(float)( X
- item
->x
) / item
->width
* 100.0f
);
453 mplEventHandling( item
->msg
,item
->value
);
457 btnModify( item
->msg
, ( 1. - (float)( Y
- item
->y
) / item
->height
) * 100.0f
);
458 mplEventHandling( item
->msg
,item
->value
);
462 mplEventHandling( item
->msg
,value
);
466 case wsRRMouseButton
:
467 gtkShow( evShowPopUpMenu
,NULL
);
470 // --- rolled mouse ... de szar :)))
471 case wsP5MouseButton
: value
=-2.5f
; goto rollerhandled
;
472 case wsP4MouseButton
: value
= 2.5f
;
474 item
=&appMPlayer
.Items
[currentselected
];
475 if ( ( item
->type
== itHPotmeter
)||( item
->type
== itVPotmeter
)||( item
->type
== itPotmeter
) )
478 btnModify( item
->msg
,item
->value
);
479 mplEventHandling( item
->msg
,item
->value
);
485 item
=&appMPlayer
.Items
[SelectedItem
];
489 wsMoveWindow( &appMPlayer
.mainWindow
,False
,RX
- abs( sx
),RY
- abs( sy
) );
493 mplMenuMouseHandle( X
,Y
,RX
,RY
);
496 item
->value
=(float)( X
- item
->x
) / item
->width
* 100.0f
;
499 item
->value
=(1. - (float)( Y
- item
->y
) / item
->height
) * 100.0f
;
502 item
->value
=(float)( X
- item
->x
) / item
->width
* 100.0f
;
504 if ( item
->value
> 100.0f
) item
->value
=100.0f
;
505 if ( item
->value
< 0.0f
) item
->value
=0.0f
;
506 mplEventHandling( item
->msg
,item
->value
);
515 void mplMainKeyHandle( int KeyCode
,int Type
,int Key
)
519 if ( Type
!= wsKeyPressed
) return;
525 case wsXFMMPrev
: msg
=evPrev
; break;
526 case wsXFMMStop
: msg
=evStop
; break;
527 case wsXFMMPlay
: msg
=evPlaySwitchToPause
; break;
528 case wsXFMMNext
: msg
=evNext
; break;
529 case wsXFMMVolUp
: msg
=evIncVolume
; break;
530 case wsXFMMVolDown
: msg
=evDecVolume
; break;
531 case wsXFMMMute
: msg
=evMute
; break;
538 case wsEnter
: msg
=evPlay
; break;
539 case wsXF86LowerVolume
: msg
=evDecVolume
; break;
540 case wsXF86RaiseVolume
: msg
=evIncVolume
; break;
541 case wsXF86Mute
: msg
=evMute
; break;
542 case wsXF86Play
: msg
=evPlaySwitchToPause
; break;
543 case wsXF86Stop
: msg
=evStop
; break;
544 case wsXF86Prev
: msg
=evPrev
; break;
545 case wsXF86Next
: msg
=evNext
; break;
546 case wsXF86Media
: msg
=evLoad
; break;
548 if ( appMPlayer
.subWindow
.isFullScreen
)
550 if ( guiIntfStruct
.event_struct
) ((XEvent
*)guiIntfStruct
.event_struct
)->type
=None
;
551 mplEventHandling( evNormalSize
,0 );
554 default: vo_x11_putkey( Key
); return;
557 if ( msg
!= evNone
) mplEventHandling( msg
,0 );
560 /* this will be used to handle Drag&Drop files */
561 void mplDandDHandler(int num
,char** files
)
566 char* subtitles
= NULL
;
567 char* filename
= NULL
;
573 /* now fill it with new items */
574 for(f
=0; f
< num
; f
++){
575 char* str
= strdup( files
[f
] );
578 url_unescape_string(str
, files
[f
]);
580 if(stat(str
,&buf
) == 0 && S_ISDIR(buf
.st_mode
) == 0) {
581 /* this is not a directory so try to play it */
582 mp_msg( MSGT_GPLAYER
,MSGL_V
,"Received D&D %s\n",str
);
584 /* check if it is a subtitle file */
586 char* ext
= strrchr(str
,'.');
588 static char supported
[] = "utf/sub/srt/smi/rt//txt/ssa/aqt/";
591 if((len
=strlen(++ext
)) && (type
=strstr(supported
,ext
)) &&\
592 (type
-supported
)%4 == 0 && *(type
+len
) == '/'){
593 /* handle subtitle file */
594 gfree((void**)&subtitles
);
602 if (filename
== NULL
) {
604 gtkSet(gtkDelPl
,0,NULL
);
607 item
= calloc(1,sizeof(plItem
));
609 /* FIXME: decompose file name ? */
610 /* yes -- Pontscho */
611 if ( strrchr( str
,'/' ) ) {
612 char * s
= strrchr( str
,'/' ); *s
=0; s
++;
613 item
->name
= gstrdup( s
);
614 item
->path
= gstrdup( str
);
616 item
->name
= strdup(str
);
617 item
->path
= strdup("");
619 gtkSet(gtkAddPlItem
,0,(void*)item
);
621 mp_msg( MSGT_GPLAYER
,MSGL_WARN
,MSGTR_NotAFile
,str
);
627 mplSetFileName( NULL
,filename
,STREAMTYPE_FILE
);
628 if ( guiIntfStruct
.Playing
== 1 ) mplEventHandling( evStop
,0 );
629 mplEventHandling( evPlay
,0 );
632 gfree((void**)&guiIntfStruct
.Subtitlename
);
633 guiIntfStruct
.Subtitlename
= subtitles
;
634 guiLoadSubtitle(guiIntfStruct
.Subtitlename
);