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 int canc = vlc_savecancel();
109 if( InitThread( p_intf ) < 0 )
111 msg_Err( p_intf, "can't initialize intf" );
115 p_input = p_intf->p_sys->p_input;
117 while ( !p_intf->p_sys->p_vcdplayer )
119 msleep( INTF_IDLE_SLEEP );
122 p_vcdplayer = p_intf->p_sys->p_vcdplayer;
123 p_access = p_vcdplayer->p_access;
125 canc = vlc_savecancel();
126 dbg_print( INPUT_DBG_CALL, "intf initialized" );
129 while( vlc_object_alive (p_intf) )
131 vlc_mutex_lock( &p_intf->change_lock );
134 * Have we timed-out in showing a still frame?
136 if( p_intf->p_sys->b_still && !p_intf->p_sys->b_infinite_still )
138 if( p_intf->p_sys->m_still_time > 0 )
140 /* Update remaining still time */
141 dbg_print(INPUT_DBG_STILL, "updating still time");
145 p_intf->p_sys->m_still_time -= mtime - mlast;
152 /* Still time has elapsed; set to continue playing. */
153 dbg_print(INPUT_DBG_STILL, "wait time done - setting play");
154 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
155 p_intf->p_sys->m_still_time = 0;
156 p_intf->p_sys->b_still = 0;
162 * Do we have a keyboard event?
164 if( p_vout && p_intf->p_sys->b_key_pressed )
167 int i, i_action = -1;
168 struct hotkey *p_hotkeys = p_intf->p_libvlc->p_hotkeys;
170 p_intf->p_sys->b_key_pressed = false;
172 /* Find action triggered by hotkey (if any) */
173 var_Get( p_intf->p_libvlc, "key-pressed", &val );
175 dbg_print( INPUT_DBG_EVENT, "Key pressed %d", val.i_int );
177 for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
179 if( p_hotkeys[i].i_key == val.i_int )
181 i_action = p_hotkeys[i].i_action;
185 if( i_action != -1) {
188 case ACTIONID_NAV_LEFT:
189 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_LEFT - prev (%d)",
192 vcdplayer_play_prev( p_access );
193 } while (number_addend-- > 0);
196 case ACTIONID_NAV_RIGHT:
197 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_RIGHT - next (%d)",
200 vcdplayer_play_next( p_access );
201 } while (number_addend-- > 0);
204 case ACTIONID_NAV_UP:
205 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_UP - return" );
207 vcdplayer_play_return( p_access );
208 } while (number_addend-- > 0);
211 case ACTIONID_NAV_DOWN:
212 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_DOWN - default" );
213 vcdplayer_play_default( p_access );
216 case ACTIONID_NAV_ACTIVATE:
218 vcdinfo_itemid_t itemid;
219 itemid.type=p_vcdplayer->play_item.type;
221 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_ACTIVATE" );
223 if ( vcdplayer_pbc_is_on( p_vcdplayer )
224 && number_addend != 0 ) {
225 lid_t next_num=vcdinfo_selection_get_lid(p_vcdplayer->vcd,
228 if (VCDINFO_INVALID_LID != next_num) {
229 itemid.num = next_num;
230 itemid.type = VCDINFO_ITEM_TYPE_LID;
231 vcdplayer_play( p_access, itemid );
234 itemid.num = number_addend;
235 vcdplayer_play( p_access, itemid );
242 /* Any keypress gets rid of still frame waiting.
243 FIXME - should handle just the ones that cause an action.
245 if( p_intf->p_sys->b_still )
247 dbg_print(INPUT_DBG_STILL, "Playing still after activate");
248 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
249 p_intf->p_sys->b_still = 0;
250 p_intf->p_sys->b_infinite_still = 0;
251 p_intf->p_sys->m_still_time = 0;
255 unsigned int digit_entered=0;
279 number_addend += digit_entered;
280 dbg_print( INPUT_DBG_EVENT,
281 "Added %d. Number is now: %d\n",
282 digit_entered, number_addend);
290 vlc_mutex_unlock( &p_intf->change_lock );
294 p_vout = vlc_object_find( p_intf->p_sys->p_input,
295 VLC_OBJECT_VOUT, FIND_CHILD );
298 var_AddCallback( p_vout, "key-pressed", KeyEvent, p_intf );
304 msleep( INTF_IDLE_SLEEP );
309 var_DelCallback( p_vout, "key-pressed", KeyEvent, p_intf );
310 vlc_object_release( p_vout );
313 vlc_object_release( p_intf->p_sys->p_input );
314 vlc_restorecancel( canc );
317 /*****************************************************************************
319 *****************************************************************************/
320 static int InitThread( intf_thread_t * p_intf )
322 /* We might need some locking here */
323 input_thread_t * p_input;
325 p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_PARENT );
327 /* Maybe the input just died */
328 if( p_input == NULL )
331 vlc_mutex_lock( &p_intf->change_lock );
333 p_intf->p_sys->p_input = p_input;
334 p_intf->p_sys->p_vcdplayer = NULL;
336 p_intf->p_sys->b_move = false;
337 p_intf->p_sys->b_click = false;
338 p_intf->p_sys->b_key_pressed = false;
340 vlc_mutex_unlock( &p_intf->change_lock );
341 /* make sure we return a value */
345 /*****************************************************************************
346 * KeyEvent: callback for keyboard events
347 *****************************************************************************/
348 static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
349 vlc_value_t oldval, vlc_value_t newval, void *p_data )
351 intf_thread_t *p_intf = (intf_thread_t *)p_data;
352 vlc_mutex_lock( &p_intf->change_lock );
354 p_intf->p_sys->b_key_pressed = true;
356 vlc_mutex_unlock( &p_intf->change_lock );
361 /*****************************************************************************
362 * vcdIntfStillTime: function provided to demux plugin to request
364 *****************************************************************************/
365 int vcdIntfStillTime( intf_thread_t *p_intf, uint8_t i_sec )
367 vlc_mutex_lock( &p_intf->change_lock );
369 p_intf->p_sys->b_still = 1;
372 p_intf->p_sys->b_infinite_still = true;
376 p_intf->p_sys->m_still_time = MILLISECONDS_PER_SEC * i_sec;
378 vlc_mutex_unlock( &p_intf->change_lock );
383 /*****************************************************************************
384 * vcdIntfStillTime: function provided to reset still image
385 *****************************************************************************/
386 int vcdIntfResetStillTime( intf_thread_t *p_intf )
388 vlc_mutex_lock( &p_intf->change_lock );
389 p_intf->p_sys->m_still_time = 0;
390 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
391 vlc_mutex_unlock( &p_intf->change_lock );