]> git.sesse.net Git - vlc/blob - modules/access/vcdx/intf.c
Removes trailing spaces. Removes tabs.
[vlc] / modules / access / vcdx / intf.c
1 /*****************************************************************************
2  * intf.c: Video CD interface to handle user interaction and still time
3  *****************************************************************************
4  * Copyright (C) 2002,2003 the VideoLAN team
5  * $Id$
6  *
7  * Author: Rocky Bernstein <rocky@panix.com>
8  *   from DVD code by Stéphane Borel <stef@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <vlc/vlc.h>
29 #include <vlc_interface.h>
30 #include <vlc_access.h>
31
32 #include "vlc_keys.h"
33
34 #include "vcd.h"
35 #include "vcdplayer.h"
36 #include "intf.h"
37
38 /*****************************************************************************
39  * Local prototypes.
40  *****************************************************************************/
41 static int  InitThread     ( intf_thread_t *p_intf );
42 static int  KeyEvent       ( vlc_object_t *, char const *,
43                              vlc_value_t, vlc_value_t, void * );
44
45 /* Exported functions */
46 static void RunIntf        ( intf_thread_t *p_intf );
47
48 /*****************************************************************************
49  * OpenIntf: initialize dummy interface
50  *****************************************************************************/
51 int VCDOpenIntf ( vlc_object_t *p_this )
52 {
53     intf_thread_t *p_intf = (intf_thread_t *)p_this;
54
55     msg_Dbg( p_intf, "VCDOpenIntf" );
56
57     /* Allocate instance and initialize some members */
58     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
59     if( p_intf->p_sys == NULL )
60     {
61         return( VLC_EGENERIC );
62     };
63
64     p_intf->pf_run = RunIntf;
65
66     var_AddCallback( p_intf->p_libvlc, "key-pressed", KeyEvent, p_intf );
67     p_intf->p_sys->m_still_time = 0;
68     p_intf->p_sys->b_infinite_still = 0;
69     p_intf->p_sys->b_still = 0;
70
71     return( VLC_SUCCESS );
72 }
73
74 /*****************************************************************************
75  * CloseIntf: destroy dummy interface
76  *****************************************************************************/
77 void VCDCloseIntf ( vlc_object_t *p_this )
78 {
79     intf_thread_t *p_intf = (intf_thread_t *)p_this;
80     var_DelCallback( p_intf->p_libvlc, "key-pressed", KeyEvent, p_intf );
81
82     /* Destroy structure */
83     free( p_intf->p_sys );
84 }
85
86
87 /*****************************************************************************
88  * RunIntf: main loop
89  *****************************************************************************/
90 static void
91 RunIntf( intf_thread_t *p_intf )
92 {
93     vlc_object_t      * p_vout = NULL;
94     mtime_t             mtime = 0;
95     mtime_t             mlast = 0;
96     vcdplayer_t       * p_vcdplayer;
97     input_thread_t    * p_input;
98     access_t          * p_access;
99
100     /* What you add to the last input number entry. It accumulates all of
101        the 10_ADD keypresses */
102     int number_addend = 0;
103
104     if( InitThread( p_intf ) < 0 )
105     {
106         msg_Err( p_intf, "can't initialize intf" );
107         return;
108     }
109
110     p_input = p_intf->p_sys->p_input;
111
112     while ( !p_intf->p_sys->p_vcdplayer )
113     {
114         msleep( INTF_IDLE_SLEEP );
115     }
116  
117     p_vcdplayer = p_intf->p_sys->p_vcdplayer;
118     p_access    = p_vcdplayer->p_access;
119
120     dbg_print( INPUT_DBG_CALL, "intf initialized" );
121
122     /* Main loop */
123     while( !p_intf->b_die )
124     {
125       vlc_mutex_lock( &p_intf->change_lock );
126
127         /*
128          * Have we timed-out in showing a still frame?
129          */
130         if( p_intf->p_sys->b_still && !p_intf->p_sys->b_infinite_still )
131         {
132             if( p_intf->p_sys->m_still_time > 0 )
133             {
134                 /* Update remaining still time */
135                 dbg_print(INPUT_DBG_STILL, "updating still time");
136                 mtime = mdate();
137                 if( mlast )
138                 {
139                     p_intf->p_sys->m_still_time -= mtime - mlast;
140                 }
141
142                 mlast = mtime;
143             }
144             else
145             {
146                 /* Still time has elapsed; set to continue playing. */
147                 dbg_print(INPUT_DBG_STILL, "wait time done - setting play");
148                 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
149                 p_intf->p_sys->m_still_time = 0;
150                 p_intf->p_sys->b_still = 0;
151                 mlast = 0;
152             }
153         }
154
155       /*
156        * Do we have a keyboard event?
157        */
158       if( p_vout && p_intf->p_sys->b_key_pressed )
159         {
160           vlc_value_t val;
161           int i, i_action = -1;
162           struct hotkey *p_hotkeys = p_intf->p_libvlc->p_hotkeys;
163
164           p_intf->p_sys->b_key_pressed = VLC_FALSE;
165
166           /* Find action triggered by hotkey (if any) */
167           var_Get( p_intf->p_libvlc, "key-pressed", &val );
168
169           dbg_print( INPUT_DBG_EVENT, "Key pressed %d", val.i_int );
170
171           for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
172             {
173               if( p_hotkeys[i].i_key == val.i_int )
174                 {
175                   i_action = p_hotkeys[i].i_action;
176                 }
177             }
178
179           if( i_action != -1) {
180             switch (i_action) {
181
182             case ACTIONID_NAV_LEFT:
183               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_LEFT - prev (%d)",
184                          number_addend );
185               do {
186                 vcdplayer_play_prev( p_access );
187               }        while (number_addend-- > 0);
188               break;
189
190             case ACTIONID_NAV_RIGHT:
191               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_RIGHT - next (%d)",
192                          number_addend );
193               do {
194                 vcdplayer_play_next( p_access );
195               } while (number_addend-- > 0);
196               break;
197
198             case ACTIONID_NAV_UP:
199               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_UP - return" );
200               do {
201                 vcdplayer_play_return( p_access );
202               } while (number_addend-- > 0);
203               break;
204
205             case ACTIONID_NAV_DOWN:
206               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_DOWN - default"  );
207               vcdplayer_play_default( p_access );
208               break;
209
210             case ACTIONID_NAV_ACTIVATE:
211               {
212                 vcdinfo_itemid_t itemid;
213                 itemid.type=p_vcdplayer->play_item.type;
214
215                 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_ACTIVATE" );
216
217                 if ( vcdplayer_pbc_is_on( p_vcdplayer )
218              && number_addend != 0 ) {
219                   lid_t next_num=vcdinfo_selection_get_lid(p_vcdplayer->vcd,
220                                                            p_vcdplayer->i_lid,
221                                                            number_addend);
222                   if (VCDINFO_INVALID_LID != next_num) {
223                     itemid.num  = next_num;
224                     itemid.type = VCDINFO_ITEM_TYPE_LID;
225                     vcdplayer_play( p_access, itemid );
226                   }
227                 } else {
228                   itemid.num = number_addend;
229                   vcdplayer_play( p_access, itemid );
230                 }
231                 break;
232               }
233             }
234             number_addend = 0;
235
236             /* Any keypress gets rid of still frame waiting.
237                FIXME - should handle just the ones that cause an action.
238             */
239             if( p_intf->p_sys->b_still )
240               {
241                 dbg_print(INPUT_DBG_STILL, "Playing still after activate");
242                 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
243                 p_intf->p_sys->b_still = 0;
244                 p_intf->p_sys->b_infinite_still = 0;
245                 p_intf->p_sys->m_still_time = 0;
246               }
247
248           } else {
249             unsigned int digit_entered=0;
250
251             switch (val.i_int) {
252             case '9':
253               digit_entered++;
254             case '8':
255               digit_entered++;
256             case '7':
257               digit_entered++;
258             case '6':
259               digit_entered++;
260             case '5':
261               digit_entered++;
262             case '4':
263               digit_entered++;
264             case '3':
265               digit_entered++;
266             case '2':
267               digit_entered++;
268             case '1':
269               digit_entered++;
270             case '0':
271               {
272                 number_addend *= 10;
273                 number_addend += digit_entered;
274                 dbg_print( INPUT_DBG_EVENT,
275                            "Added %d. Number is now: %d\n",
276                            digit_entered, number_addend);
277                 break;
278               }
279             }
280           }
281         }
282
283
284       vlc_mutex_unlock( &p_intf->change_lock );
285
286       if( p_vout == NULL )
287         {
288           p_vout = vlc_object_find( p_intf->p_sys->p_input,
289                                     VLC_OBJECT_VOUT, FIND_CHILD );
290           if( p_vout )
291             {
292               var_AddCallback( p_vout, "key-pressed", KeyEvent, p_intf );
293             }
294         }
295
296
297       /* Wait a bit */
298       msleep( INTF_IDLE_SLEEP );
299     }
300
301     if( p_vout )
302     {
303         var_DelCallback( p_vout, "key-pressed", KeyEvent, p_intf );
304         vlc_object_release( p_vout );
305     }
306
307     vlc_object_release( p_intf->p_sys->p_input );
308 }
309
310 /*****************************************************************************
311  * InitThread:
312  *****************************************************************************/
313 static int InitThread( intf_thread_t * p_intf )
314 {
315     /* We might need some locking here */
316     if( !p_intf->b_die )
317     {
318         input_thread_t * p_input;
319
320         p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_PARENT );
321
322         /* Maybe the input just died */
323         if( p_input == NULL )
324         {
325             return VLC_EGENERIC;
326         }
327
328         vlc_mutex_lock( &p_intf->change_lock );
329
330         p_intf->p_sys->p_input     = p_input;
331         p_intf->p_sys->p_vcdplayer = NULL;
332
333         p_intf->p_sys->b_move  = VLC_FALSE;
334         p_intf->p_sys->b_click = VLC_FALSE;
335         p_intf->p_sys->b_key_pressed = VLC_FALSE;
336
337         vlc_mutex_unlock( &p_intf->change_lock );
338
339         return VLC_SUCCESS;
340     }
341     else
342     {
343         return VLC_EGENERIC;
344     }
345 }
346
347 /*****************************************************************************
348  * KeyEvent: callback for keyboard events
349  *****************************************************************************/
350 static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
351                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
352 {
353     intf_thread_t *p_intf = (intf_thread_t *)p_data;
354     vlc_mutex_lock( &p_intf->change_lock );
355
356     p_intf->p_sys->b_key_pressed = VLC_TRUE;
357
358     vlc_mutex_unlock( &p_intf->change_lock );
359
360     return VLC_SUCCESS;
361 }
362
363 /*****************************************************************************
364  * vcdIntfStillTime: function provided to demux plugin to request
365  * still images
366  *****************************************************************************/
367 int vcdIntfStillTime( intf_thread_t *p_intf, uint8_t i_sec )
368 {
369     vlc_mutex_lock( &p_intf->change_lock );
370
371     p_intf->p_sys->b_still = 1;
372     if( 255 == i_sec )
373     {
374         p_intf->p_sys->b_infinite_still = VLC_TRUE;
375     }
376     else
377     {
378         p_intf->p_sys->m_still_time = MILLISECONDS_PER_SEC * i_sec;
379     }
380     vlc_mutex_unlock( &p_intf->change_lock );
381
382     return VLC_SUCCESS;
383 }
384
385 /*****************************************************************************
386  * vcdIntfStillTime: function provided to reset still image
387  *****************************************************************************/
388 int vcdIntfResetStillTime( intf_thread_t *p_intf )
389 {
390     vlc_mutex_lock( &p_intf->change_lock );
391     p_intf->p_sys->m_still_time = 0;
392     var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
393     vlc_mutex_unlock( &p_intf->change_lock );
394
395     return VLC_SUCCESS;
396 }