]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/timer.cpp
Preferences consistency fixes by Christophe Mutricy <xtophe at nxtelevision d0t com>
[vlc] / modules / gui / wxwindows / timer.cpp
1 /*****************************************************************************
2  * timer.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2003 VideoLAN
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <errno.h>                                                 /* ENOMEM */
29 #include <string.h>                                            /* strerror() */
30 #include <stdio.h>
31
32 #include <vlc/vlc.h>
33 #include <vlc/aout.h>
34 #include <vlc/intf.h>
35
36 #include "wxwindows.h"
37 #include <wx/timer.h>
38
39 //void DisplayStreamDate( wxControl *, intf_thread_t *, int );
40
41 /* Callback prototypes */
42 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
43                         vlc_value_t old_val, vlc_value_t new_val, void *param );
44 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
45                        vlc_value_t old_val, vlc_value_t new_val, void *param );
46
47 /*****************************************************************************
48  * Constructor.
49  *****************************************************************************/
50 Timer::Timer( intf_thread_t *_p_intf, Interface *_p_main_interface )
51 {
52     p_intf = _p_intf;
53     p_main_interface = _p_main_interface;
54     b_init = 0;
55     i_old_playing_status = PAUSE_S;
56     i_old_rate = INPUT_RATE_DEFAULT;
57
58     /* Register callback for the intf-popupmenu variable */
59     playlist_t *p_playlist =
60         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
61                                        FIND_ANYWHERE );
62     if( p_playlist != NULL )
63     {
64         var_AddCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
65         var_AddCallback( p_playlist, "intf-show", IntfShowCB, p_intf );
66         vlc_object_release( p_playlist );
67     }
68
69     Start( 100 /*milliseconds*/, wxTIMER_CONTINUOUS );
70 }
71
72 Timer::~Timer()
73 {
74     /* Unregister callback */
75     playlist_t *p_playlist =
76         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
77                                        FIND_ANYWHERE );
78     if( p_playlist != NULL )
79     {
80         var_DelCallback( p_playlist, "intf-popupmenu", PopupMenuCB, p_intf );
81         var_DelCallback( p_playlist, "intf-show", IntfShowCB, p_intf );
82         vlc_object_release( p_playlist );
83     }
84 }
85
86 /*****************************************************************************
87  * Private methods.
88  *****************************************************************************/
89
90 /*****************************************************************************
91  * Manage: manage main thread messages
92  *****************************************************************************
93  * In this function, called approx. 10 times a second, we check what the
94  * main program wanted to tell us.
95  *****************************************************************************/
96 void Timer::Notify()
97 {
98     input_thread_t *p_input = NULL;
99 #if defined( __WXMSW__ ) /* Work-around a bug with accelerators */
100     if( !b_init )
101     {
102         p_main_interface->Init();
103         b_init = VLC_TRUE;
104     }
105 #endif
106
107     vlc_mutex_lock( &p_intf->change_lock );
108
109     /* Update the input */
110     if( p_intf->p_sys->p_input == NULL )
111     {
112         playlist_t *p_playlist =
113             (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
114                                            FIND_ANYWHERE );
115         if( p_playlist != NULL )
116         {
117             p_intf->p_sys->p_input = p_playlist->p_input;
118             vlc_object_release( p_playlist );
119         }
120
121         /* Refresh interface */
122         if( p_intf->p_sys->p_input )
123         {
124             p_main_interface->slider->SetValue( 0 );
125             b_old_seekable = VLC_FALSE;
126             b_disc_shown = VLC_FALSE;
127
128             p_main_interface->statusbar->SetStatusText(
129                 wxU(p_intf->p_sys->p_input->input.p_item->psz_name), 2 );
130
131             p_main_interface->TogglePlayButton( PLAYING_S );
132             i_old_playing_status = PLAYING_S;
133         }
134     }
135     else if( p_intf->p_sys->p_input->b_dead )
136     {
137         /* Hide slider and Disc Buttons */
138         p_main_interface->disc_frame->Hide();
139         p_main_interface->slider_sizer->Hide(
140             p_main_interface->disc_frame );
141         p_main_interface->slider_sizer->Layout();
142         p_main_interface->slider_sizer->Fit( p_main_interface->slider_frame );
143
144         p_main_interface->slider_frame->Hide();
145         p_main_interface->frame_sizer->Hide(
146             p_main_interface->slider_frame );
147         p_main_interface->frame_sizer->Layout();
148         p_main_interface->frame_sizer->Fit( p_main_interface );
149
150         p_main_interface->TogglePlayButton( PAUSE_S );
151         i_old_playing_status = PAUSE_S;
152
153         p_main_interface->statusbar->SetStatusText( wxT(""), 0 );
154         p_main_interface->statusbar->SetStatusText( wxT(""), 2 );
155
156         p_intf->p_sys->p_input = NULL;
157     }
158
159     if( p_intf->p_sys->p_input )
160     {
161         input_thread_t *p_input = p_intf->p_sys->p_input;
162         vlc_value_t val;
163
164         if( !p_input->b_die )
165         {
166             vlc_value_t pos;
167
168             /* New input or stream map change */
169             p_intf->p_sys->b_playing = 1;
170
171             /* Update the item name */
172             p_main_interface->statusbar->SetStatusText(
173                 wxU(p_intf->p_sys->p_input->input.p_item->psz_name), 2 );
174
175             /* Manage the slider */
176             /* FIXME --fenrir */
177             /* Change the name of b_old_seekable into b_show_bar or something like that */
178             var_Get( p_input, "position", &pos );
179
180             vlc_value_t val;
181             var_Change( p_input, "title", VLC_VAR_CHOICESCOUNT, &val, NULL );
182             if( val.i_int > 0 && !b_disc_shown )
183             {
184                 b_disc_shown = VLC_TRUE;
185                 vlc_value_t val;
186
187                     #define HELP_MENU N_("Menu")
188                     #define HELP_PCH N_("Previous chapter")
189                     #define HELP_NCH N_("Next chapter")
190                     #define HELP_PTR N_("Previous track")
191                     #define HELP_NTR N_("Next track")
192
193                 var_Change( p_input, "chapter", VLC_VAR_CHOICESCOUNT, &val,
194                             NULL );
195
196                 if( val.i_int > 0 )
197                 {
198                     p_main_interface->disc_menu_button->Show();
199                     p_main_interface->disc_sizer->Show(
200                         p_main_interface->disc_menu_button );
201                     p_main_interface->disc_sizer->Layout();
202                     p_main_interface->disc_sizer->Fit(
203                         p_main_interface->disc_frame );
204
205                     p_main_interface->disc_menu_button->SetToolTip(
206                         wxU(_( HELP_MENU ) ) );
207                     p_main_interface->disc_prev_button->SetToolTip(
208                         wxU(_( HELP_PCH ) ) );
209                     p_main_interface->disc_next_button->SetToolTip(
210                         wxU(_( HELP_NCH ) ) );
211                 }
212                 else
213                 {
214                     p_main_interface->disc_menu_button->Hide();
215                     p_main_interface->disc_sizer->Hide(
216                         p_main_interface->disc_menu_button );
217
218                     p_main_interface->disc_prev_button->SetToolTip(
219                         wxU(_( HELP_PTR ) ) );
220                     p_main_interface->disc_next_button->SetToolTip(
221                         wxU(_( HELP_NTR ) ) );
222                 }
223
224                 p_main_interface->disc_frame->Show();
225                 p_main_interface->slider_sizer->Show(
226                     p_main_interface->disc_frame );
227             }
228
229             if( ! b_old_seekable )
230             {
231                 if( pos.f_float > 0.0 )
232                 {
233                     /* Done like this, as it's the only way to know if the */
234                     /* slider has to be displayed */
235                     b_old_seekable = VLC_TRUE;
236                     p_main_interface->slider_frame->Show();
237                     p_main_interface->frame_sizer->Show(
238                         p_main_interface->slider_frame );
239                     p_main_interface->frame_sizer->Layout();
240                     p_main_interface->frame_sizer->Fit( p_main_interface );
241                 }
242             }
243
244             if( p_intf->p_sys->b_playing && b_old_seekable )
245             {
246                 /* Update the slider if the user isn't dragging it. */
247                 if( p_intf->p_sys->b_slider_free )
248                 {
249                     char psz_time[ MSTRTIME_MAX_SIZE ];
250                     char psz_total[ MSTRTIME_MAX_SIZE ];
251                     vlc_value_t time;
252                     mtime_t i_seconds;
253
254                     /* Update the value */
255                     if( pos.f_float >= 0.0 )
256                     {
257                         p_intf->p_sys->i_slider_pos =
258                             (int)(SLIDER_MAX_POS * pos.f_float);
259
260                         p_main_interface->slider->SetValue(
261                             p_intf->p_sys->i_slider_pos );
262
263                         var_Get( p_intf->p_sys->p_input, "time", &time );
264                         i_seconds = time.i_time / 1000000;
265                         secstotimestr ( psz_time, i_seconds );
266
267                         var_Get( p_intf->p_sys->p_input, "length",  &time );
268                         i_seconds = time.i_time / 1000000;
269                         secstotimestr ( psz_total, i_seconds );
270
271                         p_main_interface->statusbar->SetStatusText(
272                             wxU(psz_time) + wxString(wxT(" / ")) +
273                             wxU(psz_total), 0 );
274                     }
275                 }
276             }
277 #if 0
278         vlc_mutex_lock( &p_input->stream.stream_lock );
279             if( p_intf->p_sys->p_input->stream.b_seekable && !b_old_seekable )
280             {
281                 /* Done like this because b_seekable is set slightly after
282                  * the new input object is available. */
283                 b_old_seekable = VLC_TRUE;
284                 p_main_interface->slider_frame->Show();
285                 p_main_interface->frame_sizer->Show(
286                     p_main_interface->slider_frame );
287                 p_main_interface->frame_sizer->Layout();
288                 p_main_interface->frame_sizer->Fit( p_main_interface );
289             }
290             if( p_input->stream.b_seekable && p_intf->p_sys->b_playing )
291             {
292                 /* Update the slider if the user isn't dragging it. */
293                 if( p_intf->p_sys->b_slider_free )
294                 {
295                     vlc_value_t pos;
296                     char psz_time[ MSTRTIME_MAX_SIZE ];
297                     char psz_total[ MSTRTIME_MAX_SIZE ];
298                     vlc_value_t time;
299                     mtime_t i_seconds;
300
301                     /* Update the value */
302                     var_Get( p_input, "position", &pos );
303                     if( pos.f_float >= 0.0 )
304                     {
305                         p_intf->p_sys->i_slider_pos =
306                             (int)(SLIDER_MAX_POS * pos.f_float);
307
308                         p_main_interface->slider->SetValue(
309                             p_intf->p_sys->i_slider_pos );
310
311                         var_Get( p_intf->p_sys->p_input, "time", &time );
312                         i_seconds = time.i_time / 1000000;
313                         secstotimestr ( psz_time, i_seconds );
314
315                         var_Get( p_intf->p_sys->p_input, "length",  &time );
316                         i_seconds = time.i_time / 1000000;
317                         secstotimestr ( psz_total, i_seconds );
318
319                         p_main_interface->statusbar->SetStatusText(
320                             wxU(psz_time) + wxString(wxT(" / ")) +
321                             wxU(psz_total), 0 );
322                     }
323                 }
324             }
325         vlc_mutex_unlock( &p_input->stream.stream_lock );
326 #endif
327             /* Take care of the volume, etc... */
328             p_main_interface->Update();
329
330             /* Manage Playing status */
331             var_Get( p_input, "state", &val );
332             if( i_old_playing_status != val.i_int )
333             {
334                 if( val.i_int == PAUSE_S )
335                 {
336                     p_main_interface->TogglePlayButton( PAUSE_S );
337                 }
338                 else
339                 {
340                     p_main_interface->TogglePlayButton( PLAYING_S );
341                 }
342                 i_old_playing_status = val.i_int;
343             }
344
345             /* Manage Speed status */
346             var_Get( p_input, "rate", &val );
347             if( i_old_rate != val.i_int )
348             {
349                 p_main_interface->statusbar->SetStatusText(
350                     wxString::Format(wxT("x%.2f"),
351                     (float)INPUT_RATE_DEFAULT / val.i_int ), 1 );
352                 i_old_rate = val.i_int;
353             }
354         }
355
356     }
357     else if( p_intf->p_sys->b_playing && !p_intf->b_die )
358     {
359         p_intf->p_sys->b_playing = 0;
360         p_main_interface->TogglePlayButton( PAUSE_S );
361         i_old_playing_status = PAUSE_S;
362     }
363
364     /* Show the interface, if requested */
365     if( p_intf->p_sys->b_intf_show )
366     {
367         p_main_interface->Raise();
368         p_intf->p_sys->b_intf_show = VLC_FALSE;
369     }
370
371     if( p_intf->b_die )
372     {
373         vlc_mutex_unlock( &p_intf->change_lock );
374
375         /* Prepare to die, young Skywalker */
376         p_main_interface->Close(TRUE);
377         return;
378     }
379
380     vlc_mutex_unlock( &p_intf->change_lock );
381 }
382
383 /*****************************************************************************
384  * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.
385  *  We don't show the menu directly here because we don't want the
386  *  caller to block for a too long time.
387  *****************************************************************************/
388 static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
389                         vlc_value_t old_val, vlc_value_t new_val, void *param )
390 {
391     intf_thread_t *p_intf = (intf_thread_t *)param;
392
393     if( p_intf->p_sys->pf_show_dialog )
394     {
395         p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU,
396                                        new_val.b_bool, 0 );
397     }
398
399     return VLC_SUCCESS;
400 }
401
402 /*****************************************************************************
403  * IntfShowCB: callback triggered by the intf-show playlist variable.
404  *****************************************************************************/
405 static int IntfShowCB( vlc_object_t *p_this, const char *psz_variable,
406                        vlc_value_t old_val, vlc_value_t new_val, void *param )
407 {
408     intf_thread_t *p_intf = (intf_thread_t *)param;
409     p_intf->p_sys->b_intf_show = VLC_TRUE;
410
411     return VLC_SUCCESS;
412 }