1 /*****************************************************************************
2 * intf.c: Video CD interface to handle user interaction and still time
3 *****************************************************************************
4 * Copyright (C) 2002,2003 the VideoLAN team
7 * Author: Rocky Bernstein <rocky@panix.com>
8 * from DVD code by Stéphane Borel <stef@via.ecp.fr>
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.
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.
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 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_interface.h>
34 #include <vlc_access.h>
39 #include "vcdplayer.h"
42 /*****************************************************************************
44 *****************************************************************************/
45 static int InitThread ( intf_thread_t *p_intf );
46 static int KeyEvent ( vlc_object_t *, char const *,
47 vlc_value_t, vlc_value_t, void * );
49 /* Exported functions */
50 static void RunIntf ( intf_thread_t *p_intf );
52 /*****************************************************************************
53 * OpenIntf: initialize dummy interface
54 *****************************************************************************/
55 int VCDOpenIntf ( vlc_object_t *p_this )
57 intf_thread_t *p_intf = (intf_thread_t *)p_this;
59 msg_Dbg( p_intf, "VCDOpenIntf" );
61 /* Allocate instance and initialize some members */
62 p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
63 if( p_intf->p_sys == NULL )
65 return( VLC_EGENERIC );
68 p_intf->pf_run = RunIntf;
70 var_AddCallback( p_intf->p_libvlc, "key-pressed", KeyEvent, p_intf );
71 p_intf->p_sys->m_still_time = 0;
72 p_intf->p_sys->b_infinite_still = 0;
73 p_intf->p_sys->b_still = 0;
75 return( VLC_SUCCESS );
78 /*****************************************************************************
79 * CloseIntf: destroy dummy interface
80 *****************************************************************************/
81 void VCDCloseIntf ( vlc_object_t *p_this )
83 intf_thread_t *p_intf = (intf_thread_t *)p_this;
84 var_DelCallback( p_intf->p_libvlc, "key-pressed", KeyEvent, p_intf );
86 /* Destroy structure */
87 free( p_intf->p_sys );
91 /*****************************************************************************
93 *****************************************************************************/
95 RunIntf( intf_thread_t *p_intf )
97 vlc_object_t * p_vout = NULL;
100 vcdplayer_t * p_vcdplayer;
101 input_thread_t * p_input;
104 /* What you add to the last input number entry. It accumulates all of
105 the 10_ADD keypresses */
106 int number_addend = 0;
108 if( InitThread( p_intf ) < 0 )
110 msg_Err( p_intf, "can't initialize intf" );
114 p_input = p_intf->p_sys->p_input;
116 while ( !p_intf->p_sys->p_vcdplayer )
118 msleep( INTF_IDLE_SLEEP );
121 p_vcdplayer = p_intf->p_sys->p_vcdplayer;
122 p_access = p_vcdplayer->p_access;
124 dbg_print( INPUT_DBG_CALL, "intf initialized" );
127 while( vlc_object_alive (p_intf) )
129 vlc_mutex_lock( &p_intf->change_lock );
132 * Have we timed-out in showing a still frame?
134 if( p_intf->p_sys->b_still && !p_intf->p_sys->b_infinite_still )
136 if( p_intf->p_sys->m_still_time > 0 )
138 /* Update remaining still time */
139 dbg_print(INPUT_DBG_STILL, "updating still time");
143 p_intf->p_sys->m_still_time -= mtime - mlast;
150 /* Still time has elapsed; set to continue playing. */
151 dbg_print(INPUT_DBG_STILL, "wait time done - setting play");
152 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
153 p_intf->p_sys->m_still_time = 0;
154 p_intf->p_sys->b_still = 0;
160 * Do we have a keyboard event?
162 if( p_vout && p_intf->p_sys->b_key_pressed )
165 int i, i_action = -1;
166 struct hotkey *p_hotkeys = p_intf->p_libvlc->p_hotkeys;
168 p_intf->p_sys->b_key_pressed = false;
170 /* Find action triggered by hotkey (if any) */
171 var_Get( p_intf->p_libvlc, "key-pressed", &val );
173 dbg_print( INPUT_DBG_EVENT, "Key pressed %d", val.i_int );
175 for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
177 if( p_hotkeys[i].i_key == val.i_int )
179 i_action = p_hotkeys[i].i_action;
183 if( i_action != -1) {
186 case ACTIONID_NAV_LEFT:
187 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_LEFT - prev (%d)",
190 vcdplayer_play_prev( p_access );
191 } while (number_addend-- > 0);
194 case ACTIONID_NAV_RIGHT:
195 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_RIGHT - next (%d)",
198 vcdplayer_play_next( p_access );
199 } while (number_addend-- > 0);
202 case ACTIONID_NAV_UP:
203 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_UP - return" );
205 vcdplayer_play_return( p_access );
206 } while (number_addend-- > 0);
209 case ACTIONID_NAV_DOWN:
210 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_DOWN - default" );
211 vcdplayer_play_default( p_access );
214 case ACTIONID_NAV_ACTIVATE:
216 vcdinfo_itemid_t itemid;
217 itemid.type=p_vcdplayer->play_item.type;
219 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_ACTIVATE" );
221 if ( vcdplayer_pbc_is_on( p_vcdplayer )
222 && number_addend != 0 ) {
223 lid_t next_num=vcdinfo_selection_get_lid(p_vcdplayer->vcd,
226 if (VCDINFO_INVALID_LID != next_num) {
227 itemid.num = next_num;
228 itemid.type = VCDINFO_ITEM_TYPE_LID;
229 vcdplayer_play( p_access, itemid );
232 itemid.num = number_addend;
233 vcdplayer_play( p_access, itemid );
240 /* Any keypress gets rid of still frame waiting.
241 FIXME - should handle just the ones that cause an action.
243 if( p_intf->p_sys->b_still )
245 dbg_print(INPUT_DBG_STILL, "Playing still after activate");
246 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
247 p_intf->p_sys->b_still = 0;
248 p_intf->p_sys->b_infinite_still = 0;
249 p_intf->p_sys->m_still_time = 0;
253 unsigned int digit_entered=0;
277 number_addend += digit_entered;
278 dbg_print( INPUT_DBG_EVENT,
279 "Added %d. Number is now: %d\n",
280 digit_entered, number_addend);
288 vlc_mutex_unlock( &p_intf->change_lock );
292 p_vout = vlc_object_find( p_intf->p_sys->p_input,
293 VLC_OBJECT_VOUT, FIND_CHILD );
296 var_AddCallback( p_vout, "key-pressed", KeyEvent, p_intf );
302 msleep( INTF_IDLE_SLEEP );
307 var_DelCallback( p_vout, "key-pressed", KeyEvent, p_intf );
308 vlc_object_release( p_vout );
311 vlc_object_release( p_intf->p_sys->p_input );
314 /*****************************************************************************
316 *****************************************************************************/
317 static int InitThread( intf_thread_t * p_intf )
319 /* We might need some locking here */
320 if( vlc_object_alive (p_intf) )
322 input_thread_t * p_input;
324 p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_PARENT );
326 /* Maybe the input just died */
327 if( p_input == NULL )
332 vlc_mutex_lock( &p_intf->change_lock );
334 p_intf->p_sys->p_input = p_input;
335 p_intf->p_sys->p_vcdplayer = NULL;
337 p_intf->p_sys->b_move = false;
338 p_intf->p_sys->b_click = false;
339 p_intf->p_sys->b_key_pressed = false;
341 vlc_mutex_unlock( &p_intf->change_lock );
351 /*****************************************************************************
352 * KeyEvent: callback for keyboard events
353 *****************************************************************************/
354 static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
355 vlc_value_t oldval, vlc_value_t newval, void *p_data )
357 intf_thread_t *p_intf = (intf_thread_t *)p_data;
358 vlc_mutex_lock( &p_intf->change_lock );
360 p_intf->p_sys->b_key_pressed = true;
362 vlc_mutex_unlock( &p_intf->change_lock );
367 /*****************************************************************************
368 * vcdIntfStillTime: function provided to demux plugin to request
370 *****************************************************************************/
371 int vcdIntfStillTime( intf_thread_t *p_intf, uint8_t i_sec )
373 vlc_mutex_lock( &p_intf->change_lock );
375 p_intf->p_sys->b_still = 1;
378 p_intf->p_sys->b_infinite_still = true;
382 p_intf->p_sys->m_still_time = MILLISECONDS_PER_SEC * i_sec;
384 vlc_mutex_unlock( &p_intf->change_lock );
389 /*****************************************************************************
390 * vcdIntfStillTime: function provided to reset still image
391 *****************************************************************************/
392 int vcdIntfResetStillTime( intf_thread_t *p_intf )
394 vlc_mutex_lock( &p_intf->change_lock );
395 p_intf->p_sys->m_still_time = 0;
396 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
397 vlc_mutex_unlock( &p_intf->change_lock );